|
From: libvidcap c. m. <lib...@li...> - 2007-09-08 20:22:15
|
Revision: 10
http://libvidcap.svn.sourceforge.net/libvidcap/?rev=10&view=rev
Author: bcholew
Date: 2007-09-08 13:22:13 -0700 (Sat, 08 Sep 2007)
Log Message:
-----------
Moved media type specification to bind-time. Tidied up a little. Changed spelling of some fourcc strings. Changed an error message.
Modified Paths:
--------------
trunk/src/directshow/DirectShowSource.cpp
trunk/src/vidcap.c
Modified: trunk/src/directshow/DirectShowSource.cpp
===================================================================
--- trunk/src/directshow/DirectShowSource.cpp 2007-09-07 21:53:30 UTC (rev 9)
+++ trunk/src/directshow/DirectShowSource.cpp 2007-09-08 20:22:13 UTC (rev 10)
@@ -144,7 +144,6 @@
// register filter graph - to monitor for errors during capture
// FIXME: Is this too early? Should we only do it during captures?
- // FIXME: Consider renaming to filterGraphMediaEventInterface
dshowMgr_->registerSrcGraph(this, pMediaEventIF_);
InitializeCriticalSection(&captureMutex_);
@@ -245,39 +244,12 @@
goto bail_3;
}
- // Get the appropriate source media type
- AM_MEDIA_TYPE * pAmMediaType = nativeMediaType_;
- if ( !pAmMediaType )
- {
- log_error("failed to match media type\n");
- goto bail_3;
- }
-
- // set the frame rate
- VIDEOINFOHEADER * vih = (VIDEOINFOHEADER *) pAmMediaType->pbFormat;
- vih->AvgTimePerFrame = 10000000 *
- sourceContext_->fmt_native.fps_denominator /
- sourceContext_->fmt_native.fps_numerator;
-
- // set the dimensions
- vih->bmiHeader.biWidth = sourceContext_->fmt_native.width;
- vih->bmiHeader.biHeight = sourceContext_->fmt_native.height;
-
- // set the stream's media type
- hr = pStreamConfig_->SetFormat(pAmMediaType);
- if ( FAILED(hr) )
- {
- log_error("failed setting stream format (%d)\n", hr);
- goto bail_4;
- }
-
// Set sample grabber's media type to match that of the source
- //FIXME: do at bind time
- hr = pSampleGrabberIF_->SetMediaType(pAmMediaType);
+ hr = pSampleGrabberIF_->SetMediaType(nativeMediaType_);
if ( FAILED(hr) )
{
log_error("failed to set grabber media type (%d)\n", hr);
- goto bail_4;
+ goto bail_3;
}
hr = CoCreateInstance(CLSID_NullRenderer,
@@ -289,7 +261,7 @@
if ( FAILED(hr) )
{
log_error("failed creating a NULL renderer (%d)\n", hr);
- goto bail_4;
+ goto bail_3;
}
//FIXME: use actual device name
@@ -297,7 +269,7 @@
if ( FAILED(hr) )
{
log_error("failed to add source (%d)\n", hr);
- goto bail_5;
+ goto bail_4;
}
hr = pFilterGraph_->AddFilter(pSampleGrabber_, L"Sample Grabber");
@@ -305,14 +277,14 @@
{
log_error("failed to add Sample Grabber to filter graph (%d)\n",
hr);
- goto bail_5;
+ goto bail_4;
}
hr = pFilterGraph_->AddFilter(pNullRenderer_, L"NullRenderer");
if ( FAILED(hr) )
{
log_error("failed to add null renderer (%d)\n", hr);
- goto bail_5;
+ goto bail_4;
}
hr = pCapGraphBuilder_->RenderStream(&PIN_CATEGORY_CAPTURE,
@@ -324,7 +296,7 @@
{
log_error("failed to connect source, grabber "
"and null renderer (%d)\n", hr);
- goto bail_5;
+ goto bail_4;
}
hr = pMediaControlIF_->Run();
@@ -343,12 +315,9 @@
log_error("failed to STOP filter graph (%ul)\n", hr);
}
-bail_5:
+bail_4:
pNullRenderer_->Release();
pNullRenderer_ = 0;
-bail_4:
- // free this at next bind time, and in destructor
- //dshowMgr_->freeMediaType(*pAmMediaType);
bail_3:
pSampleGrabberIF_->Release();
pSampleGrabberIF_ = 0;
@@ -551,18 +520,35 @@
// Can bind succeed?
if ( itCanWork )
{
- // take note of native media type, fps, dimensions
- nativeMediaType_ = candidateFmtProps[bestFmtNum].mediaFormat;
- sourceContext_->fmt_native.fps_numerator =
- fmtNative[bestFmtNum].fps_numerator;
- sourceContext_->fmt_native.fps_denominator =
- fmtNative[bestFmtNum].fps_denominator;
- sourceContext_->fmt_native.width = fmtNative[bestFmtNum].width;
- sourceContext_->fmt_native.height = fmtNative[bestFmtNum].height;
- sourceContext_->fmt_native.fourcc = fmtNative[bestFmtNum].fourcc;
+ // take note of native media type, fps, dimensions
+ nativeMediaType_ = candidateFmtProps[bestFmtNum].mediaFormat;
- //FIXME: use these values NOW, instead of waiting for
- // capture to start()
+ // set the frame rate
+ VIDEOINFOHEADER * vih = (VIDEOINFOHEADER *) nativeMediaType_->pbFormat;
+ vih->AvgTimePerFrame = 10000000 *
+ fmtNative[bestFmtNum].fps_denominator /
+ fmtNative[bestFmtNum].fps_numerator;
+
+ // set the dimensions
+ vih->bmiHeader.biWidth = fmtNative[bestFmtNum].width;
+ vih->bmiHeader.biHeight = fmtNative[bestFmtNum].height;
+
+ // set the stream's media type
+ hr = pStreamConfig_->SetFormat(nativeMediaType_);
+ if ( FAILED(hr) )
+ {
+ log_error("failed setting stream format (%d)\n", hr);
+ itCanWork = false;
+ }
+
+ // FIXME: is this necessary?
+ sourceContext_->fmt_native.fps_numerator =
+ fmtNative[bestFmtNum].fps_numerator;
+ sourceContext_->fmt_native.fps_denominator =
+ fmtNative[bestFmtNum].fps_denominator;
+ sourceContext_->fmt_native.width = fmtNative[bestFmtNum].width;
+ sourceContext_->fmt_native.height = fmtNative[bestFmtNum].height;
+ sourceContext_->fmt_native.fourcc = fmtNative[bestFmtNum].fourcc;
}
delete [] candidateFmtProps;
@@ -619,7 +605,8 @@
DirectShowSource::checkFormat(const vidcap_fmt_info * fmtNominal,
vidcap_fmt_info * fmtNative,
int formatNum,
- bool *needsFramerateEnforcing, bool *needsFormatConversion,
+ bool *needsFramerateEnforcing,
+ bool *needsFormatConversion,
AM_MEDIA_TYPE **mediaFormat) const
{
// get video stream capabilities structure #(formatNum)
@@ -650,7 +637,10 @@
width += scc.OutputGranularityX)
{
if ( width == fmtNominal->width )
+ {
matchesWidth = true;
+ break;
+ }
}
bool matchesHeight = false;
@@ -658,7 +648,10 @@
height += scc.OutputGranularityY)
{
if ( height == fmtNominal->height )
+ {
matchesHeight = true;
+ break;
+ }
}
if ( !matchesWidth || !matchesHeight )
@@ -698,23 +691,22 @@
*needsFormatConversion = ( nativeFourcc != fmtNominal->fourcc );
- if ( *needsFormatConversion &&
- (conv_conversion_func_get(nativeFourcc, fmtNominal->fourcc) == 0) )
+ if ( *needsFormatConversion )
{
+ if ( conv_conversion_func_get(nativeFourcc, fmtNominal->fourcc) == 0 )
+ {
dshowMgr_->freeMediaType(*pMediaType);
return false;
- }
+ }
- // it's suitable. fill-in the native format values
-
- fmtNative->width = fmtNominal->width;
- fmtNative->height = fmtNominal->height;
-
- if ( *needsFormatConversion )
fmtNative->fourcc = nativeFourcc;
+ }
else
fmtNative->fourcc = fmtNominal->fourcc;
+ fmtNative->width = fmtNominal->width;
+ fmtNative->height = fmtNominal->height;
+
if ( *needsFramerateEnforcing )
{
//FIXME: Use float. Drop numerator/denominator business.
@@ -727,21 +719,9 @@
fmtNative->fps_denominator = fmtNominal->fps_denominator;
}
- /*
- log_info("cf: can be satisfied with NATIVE format #%d: "
- "'%s' %dx%d %d/%d fps\n",
- formatNum,
- vidcap_fourcc_string_get(fmtNative->fourcc),
- fmtNative->width, fmtNative->height,
- fmtNative->fps_numerator,
- fmtNative->fps_denominator);
- */
-
// return this suitable media type
*mediaFormat = pMediaType;
- //FIXME: adjust framerate and dimensions now - not at capture start time
-
return true;
}
Modified: trunk/src/vidcap.c
===================================================================
--- trunk/src/vidcap.c 2007-09-07 21:53:30 UTC (rev 9)
+++ trunk/src/vidcap.c 2007-09-08 20:22:13 UTC (rev 10)
@@ -369,7 +369,7 @@
if ( !src_ctx->format_validate(src_ctx, fmt_info, &fmt_native) )
{
- log_error("invalid format %dx%d %s %d/%d\n",
+ log_error("format not supported by source: %dx%d %s %d/%d fps\n",
fmt_info->width, fmt_info->height,
vidcap_fourcc_string_get(fmt_info->fourcc),
fmt_info->fps_numerator,
@@ -497,11 +497,11 @@
case VIDCAP_FOURCC_YUY2:
return "yuy2";
case VIDCAP_FOURCC_RGB32:
- return " rgb";
+ return "rgb32";
case VIDCAP_FOURCC_RGB24:
- return " r24";
+ return "rgb24";
case VIDCAP_FOURCC_RGB555:
- return "r555";
+ return "rgb555";
case VIDCAP_FOURCC_YVU9:
return "yvu9";
case VIDCAP_FOURCC_2VUY:
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: libvidcap c. m. <lib...@li...> - 2007-09-11 13:15:50
|
Revision: 11
http://libvidcap.svn.sourceforge.net/libvidcap/?rev=11&view=rev
Author: bcholew
Date: 2007-09-11 06:15:47 -0700 (Tue, 11 Sep 2007)
Log Message:
-----------
Correct the checks on destination buffer size when converting to i420. Add function conv_yvu9_to_i420 to format conversion repertoire.
Modified Paths:
--------------
trunk/src/conv.c
trunk/src/conv_to_i420.c
Modified: trunk/src/conv.c
===================================================================
--- trunk/src/conv.c 2007-09-08 20:22:13 UTC (rev 10)
+++ trunk/src/conv.c 2007-09-11 13:15:47 UTC (rev 11)
@@ -28,6 +28,7 @@
int conv_2vuy_to_i420(int w, int h, const char * s, char * d, int ds);
int conv_2vuy_to_yuy2(int w, int h, const char * s, char * d, int ds);
int conv_rgb24_to_rgb32(int w, int h, const char * s, char * d, int ds);
+int conv_yvu9_to_i420(int w, int h, const char * s, char * d, int ds);
struct conv_info
{
@@ -48,6 +49,8 @@
{ VIDCAP_FOURCC_2VUY, VIDCAP_FOURCC_YUY2, conv_2vuy_to_yuy2 },
{ VIDCAP_FOURCC_2VUY, VIDCAP_FOURCC_I420, conv_2vuy_to_i420 },
{ VIDCAP_FOURCC_RGB24, VIDCAP_FOURCC_RGB32, conv_rgb24_to_rgb32 },
+
+ { VIDCAP_FOURCC_YVU9, VIDCAP_FOURCC_I420, conv_yvu9_to_i420 },
};
static const int conv_list_len = sizeof(conv_list) / sizeof(struct conv_info);
Modified: trunk/src/conv_to_i420.c
===================================================================
--- trunk/src/conv_to_i420.c 2007-09-08 20:22:13 UTC (rev 10)
+++ trunk/src/conv_to_i420.c 2007-09-11 13:15:47 UTC (rev 11)
@@ -23,6 +23,7 @@
*
*/
+#include <string.h>
#include <vidcap/converters.h>
#include "logging.h"
@@ -50,7 +51,7 @@
int i, j;
- if ( dest_size < width * height * 4 / 3 )
+ if ( dest_size < width * height * 3 / 2 )
return -1;
/* yuy2 has a vertical sampling period (for u and v)
@@ -98,7 +99,7 @@
int i, j;
- if ( dest_size < width * height * 4 / 3 )
+ if ( dest_size < width * height * 3 / 2 )
return -1;
for ( i = 0; i < height / 2; ++i )
@@ -125,3 +126,50 @@
return 0;
}
+/* yvu9 is like i420, but the u and v planes
+ * are reversed and 4x4 subsampled, instead of 2x2
+ */
+int
+conv_yvu9_to_i420(int width, int height,
+ const char * src,
+ char * dst, int dest_size)
+{
+ char * dst_y = dst;
+ char * dst_u_even = dst + width * height;
+ char * dst_u_odd = dst_u_even + width / 2;
+ char * dst_v_even = dst_u_even + width * height / 4;
+ char * dst_v_odd = dst_v_even + width / 2;
+ const char * src_y = src;
+ const char * src_v = src_y + width * height;
+ const char * src_u = src_v + width * height / 16;
+
+ int i, j;
+
+ if ( dest_size < width * height * 3 / 2 )
+ return -1;
+
+ memcpy(dst_y, src_y, height * width);
+
+ for ( i = 0; i < height / 4; ++i )
+ {
+ for ( j = 0; j < width / 4; ++j )
+ {
+ *dst_u_even++ = *src_u;
+ *dst_u_even++ = *src_u;
+ *dst_u_odd++ = *src_u;
+ *dst_u_odd++ = *src_u++;
+
+ *dst_v_even++ = *src_v;
+ *dst_v_even++ = *src_v;
+ *dst_v_odd++ = *src_v;
+ *dst_v_odd++ = *src_v++;
+ }
+
+ dst_u_even += width / 2;
+ dst_u_odd += width / 2;
+ dst_v_even += width / 2;
+ dst_v_odd += width / 2;
+ }
+
+ return 0;
+}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: libvidcap c. m. <lib...@li...> - 2007-09-11 14:46:32
|
Revision: 13
http://libvidcap.svn.sourceforge.net/libvidcap/?rev=13&view=rev
Author: bcholew
Date: 2007-09-11 07:46:28 -0700 (Tue, 11 Sep 2007)
Log Message:
-----------
Add format VIDCAP_FOURCC_BOTTOM_UP_RGB24 and function conv_bottom_up_rgb24_to_rgb32() for DirectShow-derived images. Add destination buffer size checks on some of the conversion functions. Remove unused mapVidcapFourccToDirectShowMediaType().
Modified Paths:
--------------
trunk/src/conv.c
trunk/src/conv.h
trunk/src/conv_to_rgb.c
trunk/src/conv_to_yuy2.c
trunk/src/directshow/DirectShowSource.cpp
trunk/src/directshow/DirectShowSource.h
trunk/src/vidcap.c
Modified: trunk/src/conv.c
===================================================================
--- trunk/src/conv.c 2007-09-11 13:29:44 UTC (rev 12)
+++ trunk/src/conv.c 2007-09-11 14:46:28 UTC (rev 13)
@@ -29,6 +29,7 @@
int conv_2vuy_to_yuy2(int w, int h, const char * s, char * d, int ds);
int conv_rgb24_to_rgb32(int w, int h, const char * s, char * d, int ds);
int conv_yvu9_to_i420(int w, int h, const char * s, char * d, int ds);
+int conv_bottom_up_rgb24_to_rgb32(int w, int h, const char * s, char * d, int ds);
struct conv_info
{
@@ -49,6 +50,7 @@
{ VIDCAP_FOURCC_2VUY, VIDCAP_FOURCC_YUY2, conv_2vuy_to_yuy2 },
{ VIDCAP_FOURCC_2VUY, VIDCAP_FOURCC_I420, conv_2vuy_to_i420 },
{ VIDCAP_FOURCC_RGB24, VIDCAP_FOURCC_RGB32, conv_rgb24_to_rgb32 },
+ { VIDCAP_FOURCC_BOTTOM_UP_RGB24, VIDCAP_FOURCC_RGB32, conv_bottom_up_rgb24_to_rgb32 },
{ VIDCAP_FOURCC_YVU9, VIDCAP_FOURCC_I420, conv_yvu9_to_i420 },
};
Modified: trunk/src/conv.h
===================================================================
--- trunk/src/conv.h 2007-09-11 13:29:44 UTC (rev 12)
+++ trunk/src/conv.h 2007-09-11 14:46:28 UTC (rev 13)
@@ -31,10 +31,11 @@
enum vidcap_fourccs_extra
{
- VIDCAP_FOURCC_RGB24 = 200,
- VIDCAP_FOURCC_RGB555 = 201,
- VIDCAP_FOURCC_YVU9 = 202,
- VIDCAP_FOURCC_2VUY = 203,
+ VIDCAP_FOURCC_RGB555 = 200,
+ VIDCAP_FOURCC_YVU9 = 201,
+ VIDCAP_FOURCC_2VUY = 202,
+ VIDCAP_FOURCC_RGB24 = 203,
+ VIDCAP_FOURCC_BOTTOM_UP_RGB24 = 204,
};
typedef int (*conv_func)(int width, int height,
Modified: trunk/src/conv_to_rgb.c
===================================================================
--- trunk/src/conv_to_rgb.c 2007-09-11 13:29:44 UTC (rev 12)
+++ trunk/src/conv_to_rgb.c 2007-09-11 14:46:28 UTC (rev 13)
@@ -23,6 +23,7 @@
*
*/
+//#include <string.h>
#include <vidcap/converters.h>
enum {
@@ -163,6 +164,9 @@
unsigned int * d = (unsigned int *)dest;
int i, j;
+ if ( dest_size < width * height * 4 )
+ return -1;
+
if ( !tables_initialized )
init_yuv2rgb_tables();
@@ -194,6 +198,9 @@
int i;
unsigned int * d = (unsigned int *)dest;
+ if ( dest_size < width * height * 4 )
+ return -1;
+
for ( i = 0; i < width * height; ++i )
{
*d = 0xff000000;
@@ -204,3 +211,25 @@
return 0;
}
+
+int conv_bottom_up_rgb24_to_rgb32(int width, int height,
+ const char * src,
+ char * dest, int dest_size)
+{
+ int i;
+ unsigned int * d = (unsigned int *)dest;
+ const unsigned char *src_end = src - 1 + width * height * 3;
+
+ if ( dest_size < width * height * 4 )
+ return -1;
+
+ for ( i = 0; i < width * height; ++i )
+ {
+ *d = 0xff000000;
+ *d |= ((unsigned char)(*src_end--)) << 16; // red
+ *d |= ((unsigned char)(*src_end--)) << 8; // green
+ *d++ |= ((unsigned char)(*src_end--)); // blue
+ }
+
+ return 0;
+}
Modified: trunk/src/conv_to_yuy2.c
===================================================================
--- trunk/src/conv_to_yuy2.c 2007-09-11 13:29:44 UTC (rev 12)
+++ trunk/src/conv_to_yuy2.c 2007-09-11 14:46:28 UTC (rev 13)
@@ -50,6 +50,9 @@
unsigned int * d = (unsigned int *)dest;
const unsigned int * s = (const unsigned int *)src;
+ if ( dest_size < width * height * 2 )
+ return -1;
+
for ( i = 0; i < width * height / 2; ++i )
{
*d++ = ((*s & 0xff000000) >> 8) |
Modified: trunk/src/directshow/DirectShowSource.cpp
===================================================================
--- trunk/src/directshow/DirectShowSource.cpp 2007-09-11 13:29:44 UTC (rev 12)
+++ trunk/src/directshow/DirectShowSource.cpp 2007-09-11 14:46:28 UTC (rev 13)
@@ -776,7 +776,7 @@
fourcc = VIDCAP_FOURCC_YUY2;
break;
case 0xe436eb7d:
- fourcc = VIDCAP_FOURCC_RGB24;
+ fourcc = VIDCAP_FOURCC_BOTTOM_UP_RGB24;
break;
case 0xe436eb7c:
fourcc = VIDCAP_FOURCC_RGB555;
@@ -791,26 +791,3 @@
return 0;
}
-
-int
-DirectShowSource::mapVidcapFourccToDirectShowMediaType(int fourcc, DWORD & data)
-{
- switch ( fourcc )
- {
- case VIDCAP_FOURCC_RGB32:
- data = 0xe436eb7e;
- break;
- case VIDCAP_FOURCC_I420:
- data = 0x30323449; // '024I' aka I420
- break;
- case VIDCAP_FOURCC_YUY2:
- data = 0x32595559;
- break;
- default:
- log_warn("failed to map '%s' to DShow media type\n",
- vidcap_fourcc_string_get(fourcc));
- return -1;
- }
-
- return 0;
-}
Modified: trunk/src/directshow/DirectShowSource.h
===================================================================
--- trunk/src/directshow/DirectShowSource.h 2007-09-11 13:29:44 UTC (rev 12)
+++ trunk/src/directshow/DirectShowSource.h 2007-09-11 14:46:28 UTC (rev 13)
@@ -81,7 +81,6 @@
BufferCB( double dblSampleTime, BYTE * pBuffer, long lBufferSize );
static int mapDirectShowMediaTypeToVidcapFourcc(DWORD data, int & fourcc);
- static int mapVidcapFourccToDirectShowMediaType(int fourcc, DWORD & data);
private:
struct sapi_src_context * sourceContext_;
Modified: trunk/src/vidcap.c
===================================================================
--- trunk/src/vidcap.c 2007-09-11 13:29:44 UTC (rev 12)
+++ trunk/src/vidcap.c 2007-09-11 14:46:28 UTC (rev 13)
@@ -500,6 +500,8 @@
return "rgb32";
case VIDCAP_FOURCC_RGB24:
return "rgb24";
+ case VIDCAP_FOURCC_BOTTOM_UP_RGB24:
+ return "bottom_up_rgb24";
case VIDCAP_FOURCC_RGB555:
return "rgb555";
case VIDCAP_FOURCC_YVU9:
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: libvidcap c. m. <lib...@li...> - 2007-09-11 18:43:53
|
Revision: 15
http://libvidcap.svn.sourceforge.net/libvidcap/?rev=15&view=rev
Author: jpgrayson
Date: 2007-09-11 11:43:51 -0700 (Tue, 11 Sep 2007)
Log Message:
-----------
Fix some signed/unsigned type mismatch warnings.
Tidy-up some spacing.
Modified Paths:
--------------
trunk/src/conv.h
trunk/src/conv_to_i420.c
trunk/src/conv_to_rgb.c
trunk/src/conv_to_yuy2.c
Modified: trunk/src/conv.h
===================================================================
--- trunk/src/conv.h 2007-09-11 15:31:16 UTC (rev 14)
+++ trunk/src/conv.h 2007-09-11 18:43:51 UTC (rev 15)
@@ -38,8 +38,7 @@
VIDCAP_FOURCC_BOTTOM_UP_RGB24 = 204,
};
-typedef int (*conv_func)(int width, int height,
- const char * src, char * dst);
+typedef int (*conv_func)(int width, int height, const char * src, char * dst);
#ifdef __cplusplus
extern "C" {
Modified: trunk/src/conv_to_i420.c
===================================================================
--- trunk/src/conv_to_i420.c 2007-09-11 15:31:16 UTC (rev 14)
+++ trunk/src/conv_to_i420.c 2007-09-11 18:43:51 UTC (rev 15)
@@ -31,18 +31,14 @@
*/
int
-vidcap_rgb32_to_i420(int width, int height,
- const char * src,
- char * dst)
+vidcap_rgb32_to_i420(int width, int height, const char * src, char * dst)
{
log_error("vidcap_rgb32_to_i420() not implemented\n");
return -1;
}
int
-vidcap_yuy2_to_i420(int width, int height,
- const char * src,
- char * dst)
+vidcap_yuy2_to_i420(int width, int height, const char * src, char * dst)
{
/* convert from a packed structure to a planar structure */
char * dst_y_even = dst;
@@ -86,9 +82,7 @@
* same except where we find the yuv components.
*/
int
-conv_2vuy_to_i420(int width, int height,
- const char * src,
- char * dst)
+conv_2vuy_to_i420(int width, int height, const char * src, char * dst)
{
char * dst_y_even = dst;
char * dst_y_odd = dst + width;
@@ -127,9 +121,7 @@
* are reversed and 4x4 subsampled, instead of 2x2
*/
int
-conv_yvu9_to_i420(int width, int height,
- const char * src,
- char * dst)
+conv_yvu9_to_i420(int width, int height, const char * src, char * dst)
{
char * dst_y = dst;
char * dst_u_even = dst + width * height;
Modified: trunk/src/conv_to_rgb.c
===================================================================
--- trunk/src/conv_to_rgb.c 2007-09-11 15:31:16 UTC (rev 14)
+++ trunk/src/conv_to_rgb.c 2007-09-11 18:43:51 UTC (rev 15)
@@ -96,14 +96,12 @@
* Dest should be width * height * 4 bytes in size.
*
* Based on the formulas found at http://en.wikipedia.org/wiki/YUV
+ *
+ * NOTE: size of dest buffer must be >= width * height * 4
*/
-/* NOTE: size of dest buffer must be >= width * height * 4
- */
-
int
-vidcap_i420_to_rgb32(int width, int height, const char * src,
- char * dest)
+vidcap_i420_to_rgb32(int width, int height, const char * src, char * dest)
{
const unsigned char * y_even;
const unsigned char * y_odd;
@@ -158,8 +156,7 @@
* includes two luminance (y) components and a single red and blue
* chroma (Cr and Cb aka v and u) sample use for both pixels.
*/
-int vidcap_yuy2_to_rgb32(int width, int height, const char * src,
- char * dest)
+int vidcap_yuy2_to_rgb32(int width, int height, const char * src, char * dest)
{
unsigned int * d = (unsigned int *)dest;
int i, j;
@@ -189,37 +186,37 @@
return 0;
}
-int conv_rgb24_to_rgb32(int width, int height, const char * src,
- char * dest)
+int conv_rgb24_to_rgb32(int width, int height, const char * src, char * dest)
{
int i;
unsigned int * d = (unsigned int *)dest;
+ const unsigned char * s = (const unsigned char *)src;
for ( i = 0; i < width * height; ++i )
{
*d = 0xff000000;
- *d |= ((unsigned char)(*src++)); // blue
- *d |= ((unsigned char)(*src++)) << 8; // green
- *d++ |= ((unsigned char)(*src++)) << 16; // red
+ *d |= *s++; /* blue */
+ *d |= (*s++) << 8; /* green */
+ *d++ |= (*s++) << 16; /* red */
}
return 0;
}
int conv_bottom_up_rgb24_to_rgb32(int width, int height,
- const char * src,
- char * dest)
+ const char * src, char * dest)
{
int i;
unsigned int * d = (unsigned int *)dest;
- const unsigned char *src_end = src - 1 + width * height * 3;
+ const unsigned char * src_end = (const unsigned char *)src +
+ width * height * 3 - 1;
for ( i = 0; i < width * height; ++i )
{
*d = 0xff000000;
- *d |= ((unsigned char)(*src_end--)) << 16; // red
- *d |= ((unsigned char)(*src_end--)) << 8; // green
- *d++ |= ((unsigned char)(*src_end--)); // blue
+ *d |= (*src_end--) << 16; /* red */
+ *d |= (*src_end--) << 8; /* green */
+ *d++ |= *src_end--; /* blue */
}
return 0;
Modified: trunk/src/conv_to_yuy2.c
===================================================================
--- trunk/src/conv_to_yuy2.c 2007-09-11 15:31:16 UTC (rev 14)
+++ trunk/src/conv_to_yuy2.c 2007-09-11 18:43:51 UTC (rev 15)
@@ -26,28 +26,24 @@
#include <vidcap/converters.h>
#include "logging.h"
-/* NOTE: size of dest buffer must be >= width * height * 2
- */
+/* NOTE: size of dest buffer must be >= width * height * 2 */
int
-vidcap_rgb32_to_yuy2(int width, int height, const char * src,
- char * dest)
+vidcap_rgb32_to_yuy2(int width, int height, const char * src, char * dest)
{
log_error("vidcap_rgb32_to_yuy2() not implemented\n");
return -1;
}
int
-vidcap_i420_to_yuy2(int width, int height, const char * src,
- char * dest)
+vidcap_i420_to_yuy2(int width, int height, const char * src, char * dest)
{
log_error("vidcap_i420_to_yuy2() not implemented\n");
return -1;
}
int
-conv_2vuy_to_yuy2(int width, int height, const char * src,
- char * dest)
+conv_2vuy_to_yuy2(int width, int height, const char * src, char * dest)
{
int i;
unsigned int * d = (unsigned int *)dest;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: libvidcap c. m. <lib...@li...> - 2007-09-13 19:25:54
|
Revision: 20
http://libvidcap.svn.sourceforge.net/libvidcap/?rev=20&view=rev
Author: bcholew
Date: 2007-09-13 12:25:43 -0700 (Thu, 13 Sep 2007)
Log Message:
-----------
Don't enforce framerate if we're reporting an error in capture callback. Define source context capture_data of -1 to be invalid. Set capture_data to -1 whenever clearing capture callback. Check if capture_callback or capture_data are invalid before calling application capture callback - in case they're cleared by another thread during callback.
Modified Paths:
--------------
trunk/src/sapi.c
trunk/src/sapi.h
trunk/src/vidcap.c
Modified: trunk/src/sapi.c
===================================================================
--- trunk/src/sapi.c 2007-09-13 18:32:29 UTC (rev 19)
+++ trunk/src/sapi.c 2007-09-13 19:25:43 UTC (rev 20)
@@ -215,11 +215,19 @@
const char * video_data, int video_data_size,
int error_status)
{
- int send_frame;
struct vidcap_capture_info cap_info;
- send_frame = enforce_framerate(src_ctx);
+ // NOTE: We may be called here by a notification thread while
+ // the main thread is clearing the src_ctx ->capture_data and
+ // ->capture_callback from within vidcap_src_capture_stop()
+ vidcap_src_capture_callback cap_callback = src_ctx->capture_callback;
+ void * cap_data = src_ctx->capture_data;
+ int send_frame = 0;
+
+ if ( !error_status )
+ send_frame = enforce_framerate(src_ctx);
+
if ( send_frame < 0 )
error_status = -1000;
@@ -251,15 +259,16 @@
cap_info.video_data_size = video_data_size;
}
- if ( send_frame || error_status )
- src_ctx->capture_callback(src_ctx, src_ctx->capture_data,
- &cap_info);
+ if ( ( send_frame || error_status ) && cap_callback && cap_data != VIDCAP_INVALID_USER_DATA )
+ {
+ cap_callback(src_ctx, cap_data, &cap_info);
- if ( cap_info.error_status )
- {
- src_ctx->src_state = src_bound;
- src_ctx->capture_callback = 0;
- src_ctx->capture_data = 0;
+ if ( cap_info.error_status )
+ {
+ src_ctx->src_state = src_bound;
+ src_ctx->capture_callback = 0;
+ src_ctx->capture_data = VIDCAP_INVALID_USER_DATA;
+ }
}
return 0;
Modified: trunk/src/sapi.h
===================================================================
--- trunk/src/sapi.h 2007-09-13 18:32:29 UTC (rev 19)
+++ trunk/src/sapi.h 2007-09-13 19:25:43 UTC (rev 20)
@@ -30,6 +30,8 @@
#include "config.h"
#endif
+#define VIDCAP_INVALID_USER_DATA ((void *)-1)
+
#include "sapi_context.h"
#ifdef __cplusplus
Modified: trunk/src/vidcap.c
===================================================================
--- trunk/src/vidcap.c 2007-09-13 18:32:29 UTC (rev 19)
+++ trunk/src/vidcap.c 2007-09-13 19:25:43 UTC (rev 20)
@@ -439,6 +439,9 @@
struct sapi_src_context * src_ctx = (struct sapi_src_context *)src;
const int sliding_window_seconds = 4;
+ if ( user_data == VIDCAP_INVALID_USER_DATA )
+ return -3;
+
if ( src_ctx->src_state != src_bound )
return -1;
@@ -458,7 +461,7 @@
if ( (ret = src_ctx->start_capture(src_ctx)) )
{
src_ctx->capture_callback = 0;
- src_ctx->capture_data = 0;
+ src_ctx->capture_data = VIDCAP_INVALID_USER_DATA;
return ret;
}
@@ -482,7 +485,7 @@
sliding_window_destroy(src_ctx->frame_times);
src_ctx->capture_callback = 0;
- src_ctx->capture_data = 0;
+ src_ctx->capture_data = VIDCAP_INVALID_USER_DATA;
return ret;
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: libvidcap c. m. <lib...@li...> - 2007-09-18 18:36:55
|
Revision: 24
http://libvidcap.svn.sourceforge.net/libvidcap/?rev=24&view=rev
Author: bcholew
Date: 2007-09-18 11:36:50 -0700 (Tue, 18 Sep 2007)
Log Message:
-----------
Don't mirror when converting bottom-up rgb24 to rgb32.
Modified Paths:
--------------
trunk/src/conv_to_rgb.c
trunk/src/directshow/DirectShowSource.cpp
Modified: trunk/src/conv_to_rgb.c
===================================================================
--- trunk/src/conv_to_rgb.c 2007-09-18 17:14:56 UTC (rev 23)
+++ trunk/src/conv_to_rgb.c 2007-09-18 18:36:50 UTC (rev 24)
@@ -206,17 +206,22 @@
int conv_bottom_up_rgb24_to_rgb32(int width, int height,
const char * src, char * dest)
{
- int i;
+ int i, j;
unsigned int * d = (unsigned int *)dest;
- const unsigned char * src_end = (const unsigned char *)src +
- width * height * 3 - 1;
+ const unsigned char * src_bot = (const unsigned char *)src +
+ width * (height - 1) * 3;
- for ( i = 0; i < width * height; ++i )
+ for ( i = 0; i < height; ++i )
{
- *d = 0xff000000;
- *d |= (*src_end--) << 16; /* red */
- *d |= (*src_end--) << 8; /* green */
- *d++ |= *src_end--; /* blue */
+ for ( j = 0; j < width; ++j )
+ {
+ *d = 0xff000000;
+ *d |= (*src_bot++) << 0; /* red */
+ *d |= (*src_bot++) << 8; /* green */
+ *d++ |= (*src_bot++) << 16; /* blue */
+ }
+
+ src_bot -= width * 6;
}
return 0;
Modified: trunk/src/directshow/DirectShowSource.cpp
===================================================================
--- trunk/src/directshow/DirectShowSource.cpp 2007-09-18 17:14:56 UTC (rev 23)
+++ trunk/src/directshow/DirectShowSource.cpp 2007-09-18 18:36:50 UTC (rev 24)
@@ -654,7 +654,7 @@
// set the dimensions
vih->bmiHeader.biWidth = fmtNative.width;
vih->bmiHeader.biHeight = fmtNative.height;
-
+log_info("will use NATIVE FOURCC '%s'\n", vidcap_fourcc_string_get(fmtNative.fourcc));
resetCapGraphFoo();
// set the stream's media type
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: libvidcap c. m. <lib...@li...> - 2007-09-26 13:55:16
|
Revision: 32
http://libvidcap.svn.sourceforge.net/libvidcap/?rev=32&view=rev
Author: bcholew
Date: 2007-09-26 06:54:23 -0700 (Wed, 26 Sep 2007)
Log Message:
-----------
Give each conversion function a descriptive name. Add function to retrieve name. Log the conversion name at bind time.
Modified Paths:
--------------
trunk/src/conv.c
trunk/src/conv.h
trunk/src/vidcap.c
Modified: trunk/src/conv.c
===================================================================
--- trunk/src/conv.c 2007-09-26 13:50:10 UTC (rev 31)
+++ trunk/src/conv.c 2007-09-26 13:54:23 UTC (rev 32)
@@ -36,23 +36,35 @@
int src_fourcc;
int dst_fourcc;
conv_func func;
+ const char *name;
};
static const struct conv_info conv_list[] =
{
- { VIDCAP_FOURCC_I420, VIDCAP_FOURCC_RGB32, vidcap_i420_to_rgb32 },
- { VIDCAP_FOURCC_YUY2, VIDCAP_FOURCC_RGB32, vidcap_yuy2_to_rgb32 },
- { VIDCAP_FOURCC_RGB32, VIDCAP_FOURCC_I420, vidcap_rgb32_to_i420 },
- { VIDCAP_FOURCC_YUY2, VIDCAP_FOURCC_I420, vidcap_yuy2_to_i420 },
- { VIDCAP_FOURCC_I420, VIDCAP_FOURCC_YUY2, vidcap_i420_to_yuy2 },
- { VIDCAP_FOURCC_RGB32, VIDCAP_FOURCC_YUY2, vidcap_rgb32_to_yuy2 },
+ { VIDCAP_FOURCC_I420, VIDCAP_FOURCC_RGB32, vidcap_i420_to_rgb32,
+ "i420->rgb32" },
+ { VIDCAP_FOURCC_YUY2, VIDCAP_FOURCC_RGB32, vidcap_yuy2_to_rgb32,
+ "yuy2->rgb32" },
+ { VIDCAP_FOURCC_RGB32, VIDCAP_FOURCC_I420, vidcap_rgb32_to_i420,
+ "rgb32->i420" },
+ { VIDCAP_FOURCC_YUY2, VIDCAP_FOURCC_I420, vidcap_yuy2_to_i420,
+ "yuy2->i420" },
+ { VIDCAP_FOURCC_I420, VIDCAP_FOURCC_YUY2, vidcap_i420_to_yuy2,
+ "i420->yuy2" },
+ { VIDCAP_FOURCC_RGB32, VIDCAP_FOURCC_YUY2, vidcap_rgb32_to_yuy2,
+ "rgb32->yuy2 (not implemented!)" },
- { VIDCAP_FOURCC_2VUY, VIDCAP_FOURCC_YUY2, conv_2vuy_to_yuy2 },
- { VIDCAP_FOURCC_2VUY, VIDCAP_FOURCC_I420, conv_2vuy_to_i420 },
- { VIDCAP_FOURCC_RGB24, VIDCAP_FOURCC_RGB32, conv_rgb24_to_rgb32 },
- { VIDCAP_FOURCC_BOTTOM_UP_RGB24, VIDCAP_FOURCC_RGB32, conv_bottom_up_rgb24_to_rgb32 },
+ { VIDCAP_FOURCC_2VUY, VIDCAP_FOURCC_YUY2, conv_2vuy_to_yuy2,
+ "2vuy->yuy2" },
+ { VIDCAP_FOURCC_2VUY, VIDCAP_FOURCC_I420, conv_2vuy_to_i420,
+ "2vuy->i420" },
+ { VIDCAP_FOURCC_RGB24, VIDCAP_FOURCC_RGB32, conv_rgb24_to_rgb32,
+ "rgb24->rgb32" },
+ { VIDCAP_FOURCC_BOTTOM_UP_RGB24, VIDCAP_FOURCC_RGB32,
+ conv_bottom_up_rgb24_to_rgb32, "bottom-up rgb24->rgb32" },
- { VIDCAP_FOURCC_YVU9, VIDCAP_FOURCC_I420, conv_yvu9_to_i420 },
+ { VIDCAP_FOURCC_YVU9, VIDCAP_FOURCC_I420, conv_yvu9_to_i420,
+ "yvu9->i420" },
};
static const int conv_list_len = sizeof(conv_list) / sizeof(struct conv_info);
@@ -99,3 +111,18 @@
}
}
+const char *
+conv_conversion_name_get(conv_func function)
+{
+ int i;
+
+ for ( i = 0; i < conv_list_len; ++i )
+ {
+ const struct conv_info * ci = &conv_list[i];
+
+ if ( ci->func == function )
+ return ci->name;
+ }
+
+ return "(ERROR: Conversion name not found)";
+}
Modified: trunk/src/conv.h
===================================================================
--- trunk/src/conv.h 2007-09-26 13:50:10 UTC (rev 31)
+++ trunk/src/conv.h 2007-09-26 13:54:23 UTC (rev 32)
@@ -50,6 +50,9 @@
int
conv_fmt_size_get(int width, int height, int fourcc);
+const char *
+conv_conversion_name_get(conv_func function);
+
#ifdef __cplusplus
}
#endif
Modified: trunk/src/vidcap.c
===================================================================
--- trunk/src/vidcap.c 2007-09-26 13:50:10 UTC (rev 31)
+++ trunk/src/vidcap.c 2007-09-26 13:54:23 UTC (rev 32)
@@ -414,6 +414,9 @@
log_oom(__FILE__, __LINE__);
return -1;
}
+
+ log_info("format bind requires conversion: %s\n",
+ conv_conversion_name_get(src_ctx->fmt_conv_func));
}
src_ctx->src_state = src_bound;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: libvidcap c. m. <lib...@li...> - 2007-09-26 15:55:31
|
Revision: 33
http://libvidcap.svn.sourceforge.net/libvidcap/?rev=33&view=rev
Author: bcholew
Date: 2007-09-26 08:55:16 -0700 (Wed, 26 Sep 2007)
Log Message:
-----------
Add function to convert rgb32 to yuy2.
Modified Paths:
--------------
trunk/src/conv.c
trunk/src/conv_to_yuy2.c
Modified: trunk/src/conv.c
===================================================================
--- trunk/src/conv.c 2007-09-26 13:54:23 UTC (rev 32)
+++ trunk/src/conv.c 2007-09-26 15:55:16 UTC (rev 33)
@@ -52,7 +52,7 @@
{ VIDCAP_FOURCC_I420, VIDCAP_FOURCC_YUY2, vidcap_i420_to_yuy2,
"i420->yuy2" },
{ VIDCAP_FOURCC_RGB32, VIDCAP_FOURCC_YUY2, vidcap_rgb32_to_yuy2,
- "rgb32->yuy2 (not implemented!)" },
+ "rgb32->yuy2" },
{ VIDCAP_FOURCC_2VUY, VIDCAP_FOURCC_YUY2, conv_2vuy_to_yuy2,
"2vuy->yuy2" },
Modified: trunk/src/conv_to_yuy2.c
===================================================================
--- trunk/src/conv_to_yuy2.c 2007-09-26 13:54:23 UTC (rev 32)
+++ trunk/src/conv_to_yuy2.c 2007-09-26 15:55:16 UTC (rev 33)
@@ -28,11 +28,62 @@
/* NOTE: size of dest buffer must be >= width * height * 2 */
+/* Based on formulas found at http://en.wikipedia.org/wiki/YUV */
int
vidcap_rgb32_to_yuy2(int width, int height, const char * src, char * dest)
{
- log_error("vidcap_rgb32_to_yuy2() not implemented\n");
- return -1;
+ unsigned char * dst_even, * dst_odd;
+ const unsigned char * src_even, * src_odd;
+ int i, j;
+
+ src_even = (const unsigned char *)src;
+ src_odd = src_even + width * 4;
+ dst_even = (unsigned char *)dest;
+ dst_odd = dest + width * 2;
+
+ for ( i = 0; i < height / 2; ++i )
+ {
+ for ( j = 0; j < width / 2; ++j )
+ {
+ /* NOTE: u and v are taken from different src samples */
+
+ short r, g, b;
+ b = *src_even++;
+ g = *src_even++;
+ r = *src_even++;
+ ++src_even;
+ *dst_even++ = (( r * 66 + g * 129 + b * 25 + 128 ) >> 8 ) + 16;
+ *dst_even++ = (( r * -38 - g * 74 + b * 112 + 128 ) >> 8 ) + 128;
+
+ b = *src_even++;
+ g = *src_even++;
+ r = *src_even++;
+ ++src_even;
+ *dst_even++ = (( r * 66 + g * 129 + b * 25 + 128 ) >> 8 ) + 16;
+ *dst_even++ = (( r * 112 - g * 94 - b * 18 + 128 ) >> 8 ) + 128;
+
+ b = *src_odd++;
+ g = *src_odd++;
+ r = *src_odd++;
+ ++src_odd;
+ *dst_odd++ = (( r * 66 + g * 129 + b * 25 + 128 ) >> 8 ) + 16;
+ *dst_odd++ = (( r * -38 - g * 74 + b * 112 + 128 ) >> 8 ) + 128;
+
+ b = *src_odd++;
+ g = *src_odd++;
+ r = *src_odd++;
+ ++src_odd;
+ *dst_odd++ = (( r * 66 + g * 129 + b * 25 + 128 ) >> 8 ) + 16;
+ *dst_odd++ = (( r * 112 - g * 94 - b * 18 + 128 ) >> 8 ) + 128;
+ }
+
+ dst_even += width * 2;
+ dst_odd += width * 2;
+ src_even += width * 4;
+ src_odd += width * 4;
+ }
+
+ return 0;
}
int
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: libvidcap c. m. <lib...@li...> - 2007-10-01 19:37:38
|
Revision: 37
http://libvidcap.svn.sourceforge.net/libvidcap/?rev=37&view=rev
Author: bcholew
Date: 2007-10-01 12:37:33 -0700 (Mon, 01 Oct 2007)
Log Message:
-----------
Pull out threading- and state-related members from DirectShowSource into new class SourceStateMachine.
Modified Paths:
--------------
trunk/src/directshow/DShowSrcManager.cpp
trunk/src/directshow/DirectShowSource.cpp
trunk/src/directshow/DirectShowSource.h
trunk/src/sapi_dshow.cpp
Added Paths:
-----------
trunk/src/directshow/SourceStateMachine.cpp
trunk/src/directshow/SourceStateMachine.h
Modified: trunk/src/directshow/DShowSrcManager.cpp
===================================================================
--- trunk/src/directshow/DShowSrcManager.cpp 2007-10-01 16:58:11 UTC (rev 36)
+++ trunk/src/directshow/DShowSrcManager.cpp 2007-10-01 19:37:33 UTC (rev 37)
@@ -35,7 +35,7 @@
#include "logging.h"
#include "DShowSrcManager.h"
-#include "DirectShowSource.h"
+#include "SourceStateMachine.h"
DShowSrcManager * DShowSrcManager::instance_ = 0;
Modified: trunk/src/directshow/DirectShowSource.cpp
===================================================================
--- trunk/src/directshow/DirectShowSource.cpp 2007-10-01 16:58:11 UTC (rev 36)
+++ trunk/src/directshow/DirectShowSource.cpp 2007-10-01 19:37:33 UTC (rev 37)
@@ -37,9 +37,12 @@
#include "DirectShowSource.h"
DirectShowSource::DirectShowSource(struct sapi_src_context *src,
- DShowSrcManager *mgr)
+ DShowSrcManager *mgr, bufferCallbackFunc cbFunc, cancelCaptureFunc cancelCaptureCB, void * parent)
: sourceContext_(src),
dshowMgr_(mgr),
+ bufferCB_(cbFunc),
+ cancelCaptureCB_(cancelCaptureCB),
+ parent_(parent),
graphMon_(0),
pSource_(0),
pCapGraphBuilder_(0),
@@ -51,41 +54,9 @@
pNullRenderer_(0),
pMediaControlIF_(0),
nativeMediaType_(0),
- graphHandle_(0),
graphIsSetup_(false),
- eventInitDone_(0),
- eventStart_(0),
- eventStop_(0),
- eventTerminate_(0),
- eventCancel_(0),
- sourceThread_(0),
- sourceThreadID_(0),
- okToSendStart_(true),
- okToSendStop_(true),
- allowCallbacks_(false),
- callbackInProgress_(false),
- callbackCancellationInProgress_(false),
- captureStopped_(true)
+ graphHandle_(0)
{
- if ( !dshowMgr_ )
- {
- log_error("NULL manager passed to DirectShowSource constructor.");
- throw std::runtime_error("NULL manager passed to DirectShowSource");
- }
-
- if ( !sourceContext_ )
- {
- log_error("NULL source context passed to DirectShowSource ctor.");
- throw std::runtime_error("NULL source context passed to constructor");
- }
-
- if ( !dshowMgr_->okayToBuildSource( getID() ) )
- {
- log_warn("Mgr won't permit construction of DirectShowSource w/id '%s'."
- " It's already been acquired.\n", getID());
- throw std::runtime_error("source already acquired");
- }
-
IBindCtx * pBindCtx = 0;
IMoniker * pMoniker = 0;
@@ -120,32 +91,8 @@
goto constructionFailure;
}
- if ( createEvents() )
- {
- log_error("failed creating events for source thread");
- goto constructionFailure;
- }
+ return;
- // pass instance to thread
- sourceThread_ = CreateThread(
- NULL,
- 0,
- (LPTHREAD_START_ROUTINE)(&DirectShowSource::waitForCmd),
- this,
- 0,
- &sourceThreadID_);
-
- if ( sourceThread_ != NULL )
- {
- // wait for signal from thread that it is ready
- WaitForSingleObject(eventInitDone_, INFINITE);
-
- return;
- }
-
- log_error("failed spinning source thread (%d)\n",
- GetLastError());
-
constructionFailure:
destroyCapGraphFoo();
@@ -156,40 +103,19 @@
pMoniker->Release();
pBindCtx->Release();
- dshowMgr_->sourceReleased( getID() );
-
throw std::runtime_error("failed source construction");
}
DirectShowSource::~DirectShowSource()
{
- log_info("Signaling source '%s' to terminate...\n",
- sourceContext_->src_info.description);
+ stop();
- // signal thread to shutdown
- if ( !SetEvent(eventTerminate_) )
- {
- log_error("failed to signal graph monitor thread to terminate (%d)\n",
- GetLastError());
- return;
- }
+ if ( nativeMediaType_ )
+ freeMediaType(*nativeMediaType_);
- // wait for thread to shutdown
- DWORD rc = WaitForSingleObject(sourceThread_, INFINITE);
+ destroyCapGraphFoo();
- if ( rc == WAIT_FAILED )
- {
- log_error("DirectShowSource: failed waiting for thread to return (%d)\n",
- GetLastError());
- }
-
- log_info("source '%s' has terminated\n",
- sourceContext_->src_info.description);
-
- CloseHandle(eventInitDone_);
- CloseHandle(eventStart_);
- CloseHandle(eventStop_);
- CloseHandle(eventTerminate_);
+ pSource_->Release();
}
int
@@ -318,12 +244,12 @@
return -1;
}
- hr = pMediaEventIF_->GetEventHandle((OAEVENT *)&graphHandle_);
- if ( FAILED(hr) )
- {
- log_error("failed to get handle for filter graph\n");
+ hr = pMediaEventIF_->GetEventHandle((OAEVENT *)&graphHandle_);
+ if ( FAILED(hr) )
+ {
+ log_error("failed to get handle for filter graph\n");
return -1;
- }
+ }
return 0;
}
@@ -360,192 +286,6 @@
}
int
-DirectShowSource::createEvents()
-{
- // create an event used to signal that the thread has been created
- eventInitDone_ = CreateEvent(
- NULL, // default security attributes
- TRUE, // manual-reset event
- FALSE, // initial state is clear
- NULL // no name
- );
-
- if ( eventInitDone_ == NULL)
- {
- log_error("DirectShowSource: failed creating initDone event (%d)\n",
- GetLastError());
- return -1;
- }
-
- // create an event used to signal thread to start capture
- eventStart_ = CreateEvent(
- NULL, // default security attributes
- TRUE, // manual-reset event
- FALSE, // initial state is clear
- NULL // no name
- );
-
- if ( eventStart_ == NULL)
- {
- log_error("DirectShowSource: failed creating start event (%d)\n",
- GetLastError());
- CloseHandle(eventInitDone_);
- return -1;
- }
-
- // create an event used to signal thread to stop capture
- eventStop_ = CreateEvent(
- NULL, // default security attributes
- TRUE, // manual-reset event
- FALSE, // initial state is clear
- NULL // no name
- );
-
- if ( eventStop_ == NULL)
- {
- log_error("DirectShowSource: failed creating stop event (%d)\n",
- GetLastError());
- CloseHandle(eventInitDone_);
- CloseHandle(eventStart_);
- return -1;
- }
-
- // create an event used to signal thread to terminate
- eventTerminate_ = CreateEvent(
- NULL, // default security attributes
- TRUE, // manual-reset event
- FALSE, // initial state is clear
- NULL // no name
- );
-
- if ( eventTerminate_ == NULL)
- {
- log_error("DirectShowSource: failed creating terminate event (%d)\n",
- GetLastError());
- CloseHandle(eventInitDone_);
- CloseHandle(eventStart_);
- CloseHandle(eventStop_);
- return -1;
- }
-
- // create an event used to signal thread to cancel capture
- eventCancel_ = CreateEvent(
- NULL, // default security attributes
- TRUE, // manual-reset event
- FALSE, // initial state is clear
- NULL // no name
- );
-
- if ( eventCancel_ == NULL)
- {
- log_error("DirectShowSource: failed creating cancel event (%d)\n",
- GetLastError());
- CloseHandle(eventInitDone_);
- CloseHandle(eventStart_);
- CloseHandle(eventStop_);
- CloseHandle(eventTerminate_);
- return -1;
- }
-
- return 0;
-}
-
-DWORD WINAPI
-DirectShowSource::waitForCmd(LPVOID lpParam)
-{
- // extract instance
- DirectShowSource * pSrc = static_cast<DirectShowSource *>(lpParam);
-
- // signal to main thread that we are ready for commands
- if ( !SetEvent(pSrc->eventInitDone_) )
- {
- log_error("failed to signal that source thread is ready (%d)\n",
- GetLastError());
- return -1;
- }
-
- enum { cancelEventIndex = 0, startEventIndex, stopEventIndex,
- terminateEventIndex };
-
- size_t numHandles = terminateEventIndex + 1;
- HANDLE * waitHandles = new HANDLE [numHandles];
-
- waitHandles[cancelEventIndex] = pSrc->eventCancel_;
- waitHandles[startEventIndex] = pSrc->eventStart_;
- waitHandles[stopEventIndex] = pSrc->eventStop_;
- waitHandles[terminateEventIndex] = pSrc->eventTerminate_;
-
- while ( true )
- {
- // wait until signaled to start or stop capture
- // OR to terminate
- DWORD rc = WaitForMultipleObjects(static_cast<DWORD>(numHandles),
- waitHandles, false, INFINITE);
-
- // get index of object that signaled
- unsigned int index = rc - WAIT_OBJECT_0;
-
- if ( rc == WAIT_FAILED )
- {
- log_warn("source wait failed. (0x%x)\n", GetLastError());
- }
- else if ( index == terminateEventIndex )
- {
- // give terminate the highest priority
-
- pSrc->terminate();
- break;
- }
- else if ( index == cancelEventIndex )
- {
- // give cancel a higher priority than start/stop
-
- if ( !ResetEvent(pSrc->eventCancel_) )
- {
- log_error("failed to reset source start event flag."
- "Terminating.\n");
- // terminate
- break;
- }
-
- pSrc->doCancelCallbacks();
- }
- else if ( index == startEventIndex )
- {
- if ( !ResetEvent(pSrc->eventStart_) )
- {
- log_error("failed to reset source start event flag."
- "Terminating.\n");
- // terminate
- break;
- }
-
- pSrc->okToSendStop_ = true;
-
- pSrc->doStart();
- }
- else if ( index == stopEventIndex )
- {
- if ( !ResetEvent(pSrc->eventStop_) )
- {
- log_error("failed to reset source stop event flag."
- "Terminating.\n");
- // terminate
- break;
- }
-
- pSrc->okToSendStart_ = true;
-
- pSrc->doStop();
- }
- }
-
- delete [] waitHandles;
-
- return 0;
-}
-
-int
DirectShowSource::resetCapGraphFoo()
{
if ( graphIsSetup_ )
@@ -643,105 +383,29 @@
return 0;
}
-void
-DirectShowSource::terminate()
-{
- doStop();
-
- if ( nativeMediaType_ )
- freeMediaType(*nativeMediaType_);
-
- destroyCapGraphFoo();
-
- pSource_->Release();
-
- dshowMgr_->sourceReleased( getID() );
-}
-
int
DirectShowSource::start()
{
- if ( !okToSendStart_ )
- return -1;
-
- okToSendStart_ = false;
-
- // signal source thread to start capturing
- if ( !SetEvent(eventStart_) )
- {
- log_error("failed to signal source to start (%d)\n",
- GetLastError());
- return -1;
- }
-
- return 0;
-}
-
-void
-DirectShowSource::doStart()
-{
if ( !setupCapGraphFoo() )
{
- allowCallbacks_ = true;
-
HRESULT hr = pMediaControlIF_->Run();
if ( SUCCEEDED(hr) )
- return;
+ return 0;
log_error("failed to run filter graph for source '%s' (%ul 0x%x)\n",
sourceContext_->src_info.description, hr, hr);
}
- else
- okToSendStart_ = true;
- allowCallbacks_ = false;
-
- // final capture callback - with error status
- sapi_src_capture_notify(sourceContext_, 0, 0, -1);
+ return -1;
}
// NOTE: This function will block until capture is
// completely stopped.
// Even when returning failure, it guarantees
// no more callbacks will occur
-int
+void
DirectShowSource::stop()
{
- while ( !okToSendStop_ )
- Sleep(10);
-
- okToSendStop_ = false;
-
- captureStopped_ = false;
-
- // signal source thread to stop capturing
- if ( !SetEvent(eventStop_) )
- {
- log_error("failed to signal source to stop (%d)\n",
- GetLastError());
-
- // Need to ensure no more callbacks arrive
- // Do this the hard way
- allowCallbacks_ = false;
- while ( callbackInProgress_ || callbackCancellationInProgress_ )
- Sleep(10);
-
- return -1;
- }
-
- // wait for source thread to indicate that capture has stopped
- // guaranteeing no more callbacks will occur after this returns
- while ( !captureStopped_ )
- Sleep(10);
-
- return 0;
-}
-
-void
-DirectShowSource::doStop()
-{
- allowCallbacks_ = false;
-
if ( graphIsSetup_ )
{
HRESULT hr = pMediaControlIF_->Stop();
@@ -760,13 +424,6 @@
// RenderStream(), but before graph's Run()?
resetCapGraphFoo();
}
-
- // make sure we're not in a callback
- while ( callbackInProgress_ )
- Sleep(10);
-
- // signal back to main thread that capture has stopped
- captureStopped_ = true;
}
int
@@ -1095,58 +752,6 @@
mediaType.pUnk->Release();
}
-void
-DirectShowSource::cancelCallbacks()
-{
- // signal source thread to cancel capturing
- if ( !SetEvent(eventCancel_) )
- {
- log_error("failed to signal source to cancel (%d)\n",
- GetLastError());
-
- // Need to ensure app is notified
- // Do it the hard way
-
- // prevent future callbacks
- allowCallbacks_ = false;
-
- // wait for current callback to finish
- while ( callbackInProgress_ )
- Sleep(10);
-
- // final capture callback - with error status
- sapi_src_capture_notify(sourceContext_, 0, 0, -1);
- }
-}
-
-void
-DirectShowSource::doCancelCallbacks()
-{
- callbackCancellationInProgress_ = true;
-
- // has capture been stopped already?
- if ( !allowCallbacks_ )
- {
- callbackCancellationInProgress_ = false;
- return;
- }
-
- // prevent future callbacks
- allowCallbacks_ = false;
-
- // block until current callback is not in progress
- while ( callbackInProgress_ )
- Sleep(10);
-
- // stop callbacks before sending final callback
- doStop();
-
- // final capture callback - with error status
- sapi_src_capture_notify(sourceContext_, 0, 0, -1);
-
- callbackCancellationInProgress_ = false;
-}
-
STDMETHODIMP
DirectShowSource::QueryInterface(REFIID riid, void ** ppv)
{
@@ -1168,21 +773,7 @@
STDMETHODIMP
DirectShowSource::BufferCB( double dblSampleTime, BYTE * pBuff, long buffSize )
{
- callbackInProgress_ = true;
-
- if ( !allowCallbacks_ )
- {
- callbackInProgress_ = false;
- return 0;
- }
-
- int ret = sapi_src_capture_notify(sourceContext_,
- reinterpret_cast<const char *>(pBuff),
- static_cast<int>(buffSize), 0);
-
- callbackInProgress_ = false;
-
- return ret;
+ return bufferCB_(dblSampleTime, pBuff, buffSize, parent_);
}
int
@@ -1247,7 +838,7 @@
log_info("device removal detected\n");
// shutdown capture
- pSrc->cancelCallbacks();
+ pSrc->cancelCaptureCB_(pSrc->parent_);
}
else
{
@@ -1313,7 +904,7 @@
log_info("graph monitor stopping capture...\n");
// shutdown capture
- pSrc->cancelCallbacks();
+ pSrc->cancelCaptureCB_(pSrc->parent_);
break;
Modified: trunk/src/directshow/DirectShowSource.h
===================================================================
--- trunk/src/directshow/DirectShowSource.h 2007-10-01 16:58:11 UTC (rev 36)
+++ trunk/src/directshow/DirectShowSource.h 2007-10-01 19:37:33 UTC (rev 37)
@@ -38,12 +38,15 @@
{
public:
- DirectShowSource(struct sapi_src_context *src, DShowSrcManager *);
+ typedef int (*bufferCallbackFunc)(double, BYTE *, long, void *);
+ typedef void (*cancelCaptureFunc)(void *);
+
+ DirectShowSource(struct sapi_src_context *, DShowSrcManager *,
+ bufferCallbackFunc, cancelCaptureFunc, void *);
~DirectShowSource();
int start();
- int stop();
- void cancelCallbacks();
+ void stop();
int bindFormat(const vidcap_fmt_info * fmtInfo);
int validateFormat(const vidcap_fmt_info * fmtNominal,
vidcap_fmt_info * fmtNative) const;
@@ -57,13 +60,6 @@
}
private:
- static DWORD WINAPI waitForCmd(LPVOID);
- void terminate();
- void doStart();
- void doStop();
- void doCancelCallbacks();
- int createEvents();
-
int createCapGraphFoo();
void destroyCapGraphFoo();
int setupCapGraphFoo();
@@ -85,20 +81,22 @@
STDMETHODIMP QueryInterface(REFIID riid, void ** ppv);
// Not used
- STDMETHODIMP SampleCB( double SampleTime, IMediaSample * pSample )
+ STDMETHODIMP SampleCB( double, IMediaSample *)
{
return S_OK;
}
// The sample grabber calls us back from its deliver thread
- STDMETHODIMP
- BufferCB( double dblSampleTime, BYTE * pBuffer, long lBufferSize );
+ STDMETHODIMP BufferCB( double, BYTE *, long );
static int mapDirectShowMediaTypeToVidcapFourcc(DWORD data, int & fourcc);
private:
struct sapi_src_context * sourceContext_;
DShowSrcManager * dshowMgr_;
+ bufferCallbackFunc bufferCB_;
+ cancelCaptureFunc cancelCaptureCB_;
+ void * parent_;
GraphMonitor *graphMon_;
IBaseFilter * pSource_;
@@ -113,21 +111,6 @@
AM_MEDIA_TYPE *nativeMediaType_;
HANDLE *graphHandle_;
bool graphIsSetup_;
-
- HANDLE eventInitDone_;
- HANDLE eventStart_;
- HANDLE eventStop_;
- HANDLE eventTerminate_;
- HANDLE eventCancel_;
- void * sourceThread_;
- DWORD sourceThreadID_;
-
- bool okToSendStart_;
- bool okToSendStop_;
- bool allowCallbacks_;
- bool callbackInProgress_;
- bool callbackCancellationInProgress_;
- bool captureStopped_;
};
#endif
Added: trunk/src/directshow/SourceStateMachine.cpp
===================================================================
--- trunk/src/directshow/SourceStateMachine.cpp (rev 0)
+++ trunk/src/directshow/SourceStateMachine.cpp 2007-10-01 19:37:33 UTC (rev 37)
@@ -0,0 +1,529 @@
+//
+// libvidcap - a cross-platform video capture library
+//
+// Copyright 2007 Wimba, Inc.
+//
+// Contributors:
+// Peter Grayson <jpg...@gm...>
+// Bill Cholewka <bc...@gm...>
+//
+// libvidcap is free software; you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as
+// published by the Free Software Foundation; either version 2.1 of
+// the License, or (at your option) any later version.
+//
+// libvidcap is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this program. If not, see
+// <http://www.gnu.org/licenses/>.
+//
+
+#include <windows.h>
+
+#include "hotlist.h"
+#include "logging.h"
+#include "sapi.h"
+#include "SourceStateMachine.h"
+
+SourceStateMachine::SourceStateMachine(struct sapi_src_context *src,
+ DShowSrcManager *mgr)
+ : sourceContext_(src),
+ dshowMgr_(mgr),
+ src_(0),
+ eventInitDone_(0),
+ eventStart_(0),
+ eventStop_(0),
+ eventTerminate_(0),
+ eventCancel_(0),
+ sourceThread_(0),
+ sourceThreadID_(0),
+ okToSendStart_(true),
+ okToSendStop_(true),
+ allowCallbacks_(false),
+ callbackInProgress_(false),
+ callbackCancellationInProgress_(false),
+ captureStopped_(true)
+{
+ if ( !dshowMgr_ )
+ {
+ log_error("NULL manager passed to SourceStateMachine constructor.");
+ throw std::runtime_error("NULL manager passed to SourceStateMachine");
+ }
+
+ if ( !sourceContext_ )
+ {
+ log_error("NULL source context passed to SourceStateMachine ctor.");
+ throw std::runtime_error("NULL source context passed to constructor");
+ }
+
+ if ( !dshowMgr_->okayToBuildSource( getID() ) )
+ {
+ log_warn("Mgr won't permit construction of SourceStateMachine w/id '%s'."
+ " It's already been acquired.\n", getID());
+ throw std::runtime_error("source already acquired");
+ }
+
+ try
+ {
+ src_ = new DirectShowSource(src,
+ mgr,
+ (bufferCallbackFunc)&SourceStateMachine::bufferCB,
+ (cancelCaptureFunc)&SourceStateMachine::cancelCaptureCB,
+ this);
+ }
+ catch (std::runtime_error &) //check
+ {
+ log_error("failed creating dshow source\n");
+ goto constructionFailure;
+ }
+
+ if ( createEvents() )
+ {
+ log_error("failed creating events for source thread");
+ goto constructionFailure;
+ }
+
+ // pass instance to thread
+ sourceThread_ = CreateThread(
+ NULL,
+ 0,
+ (LPTHREAD_START_ROUTINE)(&SourceStateMachine::waitForCmd),
+ this,
+ 0,
+ &sourceThreadID_);
+
+ if ( sourceThread_ != NULL )
+ {
+ // wait for signal from thread that it is ready
+ WaitForSingleObject(eventInitDone_, INFINITE);
+
+ return;
+ }
+
+ log_error("failed spinning source thread (%d)\n",
+ GetLastError());
+
+constructionFailure:
+
+ throw std::runtime_error("failed source construction");
+}
+
+SourceStateMachine::~SourceStateMachine()
+{
+ log_info("Signaling source '%s' to terminate...\n",
+ sourceContext_->src_info.description);
+
+ // signal thread to shutdown
+ if ( !SetEvent(eventTerminate_) )
+ {
+ log_error("failed to signal graph monitor thread to terminate (%d)\n",
+ GetLastError());
+ return;
+ }
+
+ // wait for thread to shutdown
+ DWORD rc = WaitForSingleObject(sourceThread_, INFINITE);
+
+ if ( rc == WAIT_FAILED )
+ {
+ log_error("SourceStateMachine: failed waiting for thread to return (%d)\n",
+ GetLastError());
+ }
+
+ log_info("source '%s' has terminated\n",
+ sourceContext_->src_info.description);
+
+ CloseHandle(eventInitDone_);
+ CloseHandle(eventStart_);
+ CloseHandle(eventStop_);
+ CloseHandle(eventTerminate_);
+}
+
+int
+SourceStateMachine::createEvents()
+{
+ // create an event used to signal that the thread has been created
+ eventInitDone_ = CreateEvent(
+ NULL, // default security attributes
+ TRUE, // manual-reset event
+ FALSE, // initial state is clear
+ NULL // no name
+ );
+
+ if ( eventInitDone_ == NULL)
+ {
+ log_error("SourceStateMachine: failed creating initDone event (%d)\n",
+ GetLastError());
+ return -1;
+ }
+
+ // create an event used to signal thread to start capture
+ eventStart_ = CreateEvent(
+ NULL, // default security attributes
+ TRUE, // manual-reset event
+ FALSE, // initial state is clear
+ NULL // no name
+ );
+
+ if ( eventStart_ == NULL)
+ {
+ log_error("SourceStateMachine: failed creating start event (%d)\n",
+ GetLastError());
+ CloseHandle(eventInitDone_);
+ return -1;
+ }
+
+ // create an event used to signal thread to stop capture
+ eventStop_ = CreateEvent(
+ NULL, // default security attributes
+ TRUE, // manual-reset event
+ FALSE, // initial state is clear
+ NULL // no name
+ );
+
+ if ( eventStop_ == NULL)
+ {
+ log_error("SourceStateMachine: failed creating stop event (%d)\n",
+ GetLastError());
+ CloseHandle(eventInitDone_);
+ CloseHandle(eventStart_);
+ return -1;
+ }
+
+ // create an event used to signal thread to terminate
+ eventTerminate_ = CreateEvent(
+ NULL, // default security attributes
+ TRUE, // manual-reset event
+ FALSE, // initial state is clear
+ NULL // no name
+ );
+
+ if ( eventTerminate_ == NULL)
+ {
+ log_error("SourceStateMachine: failed creating terminate event (%d)\n",
+ GetLastError());
+ CloseHandle(eventInitDone_);
+ CloseHandle(eventStart_);
+ CloseHandle(eventStop_);
+ return -1;
+ }
+
+ // create an event used to signal thread to cancel capture
+ eventCancel_ = CreateEvent(
+ NULL, // default security attributes
+ TRUE, // manual-reset event
+ FALSE, // initial state is clear
+ NULL // no name
+ );
+
+ if ( eventCancel_ == NULL)
+ {
+ log_error("SourceStateMachine: failed creating cancel event (%d)\n",
+ GetLastError());
+ CloseHandle(eventInitDone_);
+ CloseHandle(eventStart_);
+ CloseHandle(eventStop_);
+ CloseHandle(eventTerminate_);
+ return -1;
+ }
+
+ return 0;
+}
+
+DWORD WINAPI
+SourceStateMachine::waitForCmd(LPVOID lpParam)
+{
+ // extract instance
+ SourceStateMachine * pSrc = (SourceStateMachine *)lpParam;
+
+ // signal to main thread that we are ready for commands
+ if ( !SetEvent(pSrc->eventInitDone_) )
+ {
+ log_error("failed to signal that source thread is ready (%d)\n",
+ GetLastError());
+ return -1;
+ }
+
+ enum { cancelEventIndex = 0, startEventIndex, stopEventIndex,
+ terminateEventIndex };
+
+ size_t numHandles = terminateEventIndex + 1;
+ HANDLE * waitHandles = new HANDLE [numHandles];
+
+ waitHandles[cancelEventIndex] = pSrc->eventCancel_;
+ waitHandles[startEventIndex] = pSrc->eventStart_;
+ waitHandles[stopEventIndex] = pSrc->eventStop_;
+ waitHandles[terminateEventIndex] = pSrc->eventTerminate_;
+
+ while ( true )
+ {
+ // wait until signaled to start or stop capture
+ // OR to terminate
+ DWORD rc = WaitForMultipleObjects(static_cast<DWORD>(numHandles),
+ waitHandles, false, INFINITE);
+
+ // get index of object that signaled
+ unsigned int index = rc - WAIT_OBJECT_0;
+
+ if ( rc == WAIT_FAILED )
+ {
+ log_warn("source wait failed. (0x%x)\n", GetLastError());
+ }
+ else if ( index == terminateEventIndex )
+ {
+ // give terminate the highest priority
+
+ pSrc->terminate();
+ break;
+ }
+ else if ( index == cancelEventIndex )
+ {
+ // give cancel a higher priority than start/stop
+
+ if ( !ResetEvent(pSrc->eventCancel_) )
+ {
+ log_error("failed to reset source start event flag."
+ "Terminating.\n");
+ // terminate
+ break;
+ }
+
+ pSrc->doCancelCapture();
+ }
+ else if ( index == startEventIndex )
+ {
+ if ( !ResetEvent(pSrc->eventStart_) )
+ {
+ log_error("failed to reset source start event flag."
+ "Terminating.\n");
+ // terminate
+ break;
+ }
+
+ pSrc->okToSendStop_ = true;
+
+ pSrc->doStart();
+ }
+ else if ( index == stopEventIndex )
+ {
+ if ( !ResetEvent(pSrc->eventStop_) )
+ {
+ log_error("failed to reset source stop event flag."
+ "Terminating.\n");
+ // terminate
+ break;
+ }
+
+ pSrc->okToSendStart_ = true;
+
+ pSrc->doStop();
+ }
+ }
+
+ delete [] waitHandles;
+
+ return 0;
+}
+
+void
+SourceStateMachine::terminate()
+{
+ delete src_;
+
+ dshowMgr_->sourceReleased( getID() );
+}
+
+int
+SourceStateMachine::start()
+{
+ if ( !okToSendStart_ )
+ return -1;
+
+ okToSendStart_ = false;
+
+ // signal source thread to start capturing
+ if ( !SetEvent(eventStart_) )
+ {
+ log_error("failed to signal source to start (%d)\n",
+ GetLastError());
+ return -1;
+ }
+
+ return 0;
+}
+
+void
+SourceStateMachine::doStart()
+{
+ if ( src_->start() )
+ {
+ log_error("failed to run filter graph for source '%s'\n",
+ sourceContext_->src_info.description);
+
+ allowCallbacks_ = false;
+ okToSendStart_ = true;
+
+ // final capture callback - with error status
+ sapi_src_capture_notify(sourceContext_, 0, 0, -1);
+ }
+ else
+ {
+ allowCallbacks_ = true;
+ }
+
+}
+
+// NOTE: This function will block until capture is
+// completely stopped.
+// Even when returning failure, it guarantees
+// no more callbacks will occur
+int
+SourceStateMachine::stop()
+{
+ while ( !okToSendStop_ )
+ Sleep(10);
+
+ okToSendStop_ = false;
+
+ captureStopped_ = false;
+
+ // signal source thread to stop capturing
+ if ( !SetEvent(eventStop_) )
+ {
+ log_error("failed to signal source to stop (%d)\n",
+ GetLastError());
+
+ // Need to ensure no more callbacks arrive
+ // Do this the hard way
+ allowCallbacks_ = false;
+ while ( callbackInProgress_ || callbackCancellationInProgress_ )
+ Sleep(10);
+
+ return -1;
+ }
+
+ // wait for source thread to indicate that capture has stopped
+ // guaranteeing no more callbacks will occur after this returns
+ while ( !captureStopped_ )
+ Sleep(10);
+
+ return 0;
+}
+
+void
+SourceStateMachine::doStop()
+{
+ allowCallbacks_ = false;
+
+ src_->stop();
+
+ // make sure we're not in a callback
+ while ( callbackInProgress_ )
+ Sleep(10);
+
+ // signal back to main thread that capture has stopped
+ captureStopped_ = true;
+}
+
+int
+SourceStateMachine::validateFormat(const vidcap_fmt_info * fmtNominal,
+ vidcap_fmt_info * fmtNative) const
+{
+ return src_->validateFormat(fmtNominal, fmtNative);
+}
+
+int
+SourceStateMachine::bindFormat(const vidcap_fmt_info * fmtNominal)
+{
+ return src_->bindFormat(fmtNominal);
+}
+
+void
+SourceStateMachine::cancelCaptureCB(void *parent)
+{
+ SourceStateMachine *instance = static_cast<SourceStateMachine *>(parent);
+
+ instance->cancelCapture();
+}
+
+void
+SourceStateMachine::cancelCapture()
+{
+ // signal source thread to cancel capturing
+ if ( !SetEvent(eventCancel_) )
+ {
+ log_error("failed to signal source to cancel (%d)\n",
+ GetLastError());
+
+ // Need to ensure app is notified
+ // Do it the hard way
+
+ // prevent future callbacks
+ allowCallbacks_ = false;
+
+ // wait for current callback to finish
+ while ( callbackInProgress_ )
+ Sleep(10);
+
+ // final capture callback - with error status
+ sapi_src_capture_notify(sourceContext_, 0, 0, -1);
+ }
+}
+
+void
+SourceStateMachine::doCancelCapture()
+{
+ callbackCancellationInProgress_ = true;
+
+ // has capture been stopped already?
+ if ( !allowCallbacks_ )
+ {
+ callbackCancellationInProgress_ = false;
+ return;
+ }
+
+ // prevent future callbacks
+ allowCallbacks_ = false;
+
+ // block until current callback is not in progress
+ while ( callbackInProgress_ )
+ Sleep(10);
+
+ // stop callbacks before sending final callback
+ src_->stop();
+
+ // final capture callback - with error status
+ sapi_src_capture_notify(sourceContext_, 0, 0, -1);
+
+ callbackCancellationInProgress_ = false;
+}
+
+// The sample grabber calls this from its deliver thread
+// NOTE: This function must not block, else it will cause a
+// graph's Stop() to block - which could result in a deadlock
+int
+SourceStateMachine::bufferCB( double dblSampleTime, BYTE * pBuff, long buffSize, void *context )
+{
+ SourceStateMachine *instance = static_cast<SourceStateMachine *>(context);
+
+ instance->callbackInProgress_ = true;
+
+ if ( !instance->allowCallbacks_ )
+ {
+ instance->callbackInProgress_ = false;
+ return 0;
+ }
+
+ int ret = sapi_src_capture_notify(instance->sourceContext_,
+ reinterpret_cast<const char *>(pBuff),
+ static_cast<int>(buffSize), 0);
+
+ instance->callbackInProgress_ = false;
+
+ return ret;
+}
+
Added: trunk/src/directshow/SourceStateMachine.h
===================================================================
--- trunk/src/directshow/SourceStateMachine.h (rev 0)
+++ trunk/src/directshow/SourceStateMachine.h 2007-10-01 19:37:33 UTC (rev 37)
@@ -0,0 +1,84 @@
+//
+// libvidcap - a cross-platform video capture library
+//
+// Copyright 2007 Wimba, Inc.
+//
+// Contributors:
+// Peter Grayson <jpg...@gm...>
+// Bill Cholewka <bc...@gm...>
+//
+// libvidcap is free software; you can redistribute it and/or modify
+// it under the terms of the GNU Lesser General Public License as
+// published by the Free Software Foundation; either ve...
[truncated message content] |
|
From: libvidcap c. m. <lib...@li...> - 2007-10-10 18:04:28
|
Revision: 44
http://libvidcap.svn.sourceforge.net/libvidcap/?rev=44&view=rev
Author: bcholew
Date: 2007-10-10 11:04:18 -0700 (Wed, 10 Oct 2007)
Log Message:
-----------
Prevent reference to sliding window of frame_times while processing a residual capture callback (after capture has been stopped and callback structures have been freed). Plug leak: if capture start fails, destroy sliding window of frame_times. Ensure sliding window (yes, frame_times) is destroyed when source is released. Return unique error code if capture fails due to incorrect source state.
Modified Paths:
--------------
trunk/src/sapi.c
trunk/src/vidcap.c
Modified: trunk/src/sapi.c
===================================================================
--- trunk/src/sapi.c 2007-10-09 16:28:27 UTC (rev 43)
+++ trunk/src/sapi.c 2007-10-10 18:04:18 UTC (rev 44)
@@ -92,17 +92,23 @@
{
struct timeval tv_earliest_next;
struct timeval tv_now;
- struct timeval *tv_oldest;
- const int first_time = !sliding_window_count(src_ctx->frame_times);
+ struct timeval *tv_oldest = 0;
+ int first_time = 0;
+ if ( !src_ctx->frame_times )
+ return 0;
+
+ first_time = !sliding_window_count(src_ctx->frame_times);
+
if ( gettimeofday(&tv_now, 0) )
return -1;
if ( !first_time && !tv_greater_or_equal(
&tv_now, &src_ctx->frame_time_next) )
- /* Allow frame through */
return 0;
+ /* Allow frame through */
+
tv_oldest = sliding_window_peek_front(src_ctx->frame_times);
if ( !tv_oldest )
@@ -217,9 +223,9 @@
{
struct vidcap_capture_info cap_info;
- /* NOTE: We may be called here by a notification thread while the
- * main thread is clearing capture_data and capture_callback from
- * within vidcap_src_capture_stop().
+ /* NOTE: We may be called here by the capture thread while the
+ * main thread is clearing capture_data and capture_callback
+ * from within vidcap_src_capture_stop().
*/
vidcap_src_capture_callback cap_callback = src_ctx->capture_callback;
void * cap_data = src_ctx->capture_data;
Modified: trunk/src/vidcap.c
===================================================================
--- trunk/src/vidcap.c 2007-10-09 16:28:27 UTC (rev 43)
+++ trunk/src/vidcap.c 2007-10-10 18:04:18 UTC (rev 44)
@@ -356,6 +356,9 @@
if ( src_ctx->fmt_conv_buf )
free(src_ctx->fmt_conv_buf);
+ if ( src_ctx->frame_times )
+ sliding_window_destroy(src_ctx->frame_times);
+
free(src_ctx);
return ret;
@@ -476,7 +479,7 @@
return -3;
if ( src_ctx->src_state != src_bound )
- return -1;
+ return -4;
src_ctx->frame_time_next.tv_sec = 0;
src_ctx->frame_time_next.tv_usec = 0;
@@ -495,6 +498,8 @@
{
src_ctx->capture_callback = 0;
src_ctx->capture_data = VIDCAP_INVALID_USER_DATA;
+ sliding_window_destroy(src_ctx->frame_times);
+ src_ctx->frame_times = 0;
return ret;
}
@@ -511,14 +516,14 @@
if ( src_ctx->src_state != src_capturing )
return -1;
- src_ctx->src_state = src_bound;
-
ret = src_ctx->stop_capture(src_ctx);
sliding_window_destroy(src_ctx->frame_times);
+ src_ctx->frame_times = 0;
src_ctx->capture_callback = 0;
src_ctx->capture_data = VIDCAP_INVALID_USER_DATA;
+ src_ctx->src_state = src_bound;
return ret;
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: libvidcap c. m. <lib...@li...> - 2007-10-12 16:30:12
|
Revision: 46
http://libvidcap.svn.sourceforge.net/libvidcap/?rev=46&view=rev
Author: bcholew
Date: 2007-10-12 09:30:09 -0700 (Fri, 12 Oct 2007)
Log Message:
-----------
Add generic support for images with strides. Make Mac version stride-aware. Keep linux and Windows builds stride-ignorant.
Modified Paths:
--------------
trunk/src/conv.c
trunk/src/conv.h
trunk/src/directshow/SourceStateMachine.cpp
trunk/src/sapi.c
trunk/src/sapi.h
trunk/src/sapi_context.h
trunk/src/sapi_qt.c
trunk/src/sapi_v4l.c
trunk/src/vidcap.c
Modified: trunk/src/conv.c
===================================================================
--- trunk/src/conv.c 2007-10-10 18:31:30 UTC (rev 45)
+++ trunk/src/conv.c 2007-10-12 16:30:09 UTC (rev 46)
@@ -23,7 +23,9 @@
*
*/
+#include "string.h"
#include "conv.h"
+#include "logging.h"
int conv_2vuy_to_i420(int w, int h, const char * s, char * d);
int conv_2vuy_to_yuy2(int w, int h, const char * s, char * d);
@@ -69,6 +71,150 @@
static const int conv_list_len = sizeof(conv_list) / sizeof(struct conv_info);
+static int
+destride_packed(int image_byte_width, int height, signed int stride,
+ const char * src, char * dst)
+{
+ /* destride a packed structure */
+ char * dst_even = dst;
+ char * dst_odd = dst + image_byte_width;
+ const char * src_even = src;
+ const char * src_odd = src + stride;
+
+ int i;
+ for ( i = 0; i < height / 2; ++i )
+ {
+ memcpy(dst_even, src_even, image_byte_width);
+ memcpy(dst_odd, src_odd, image_byte_width);
+
+ dst_even += 2 * image_byte_width;
+ dst_odd += 2 * image_byte_width;
+ src_even += 2 * stride;
+ src_odd += 2 * stride;
+ }
+
+ return 0;
+}
+
+static int
+destride_planar(int width, int height,
+ int u_width, int u_height,
+ int v_width, int v_height,
+ signed int y_stride, signed int u_stride, signed int v_stride,
+ const char * src, char * dst)
+{
+ char * dst_y_even = dst;
+ char * dst_y_odd = dst + width;
+ char * dst_u_even = dst + width * height;
+ char * dst_u_odd = dst_u_even + u_width;
+ char * dst_v_even = dst_u_even + u_width * u_height;
+ char * dst_v_odd = dst_v_even + v_width;
+ const char * src_y_even = src;
+ const char * src_y_odd = src + y_stride;
+ const char * src_u_even = src + y_stride * height;
+ const char * src_u_odd = src_u_even + u_stride;
+ const char * src_v_even = src_u_even + u_stride * u_height;
+ const char * src_v_odd = src_v_even + v_stride;
+
+ int i;
+
+ for ( i = 0; i < height / 2; ++i )
+ {
+ memcpy(dst_y_even, src_y_even, width);
+ memcpy(dst_y_odd, src_y_odd, width);
+
+ dst_y_even += 2 * width;
+ dst_y_odd += 2 * width;
+ src_y_even += 2 * y_stride;
+ src_y_odd += 2 * y_stride;
+ }
+
+ for ( i = 0; i < u_height / 2; ++i )
+ {
+ memcpy(dst_u_even, src_u_even, u_width);
+ memcpy(dst_u_odd, src_u_odd, u_width);
+
+ dst_u_even += 2 * u_width;
+ dst_u_odd += 2 * u_width;
+ src_u_even += 2 * u_stride;
+ src_u_odd += 2 * u_stride;
+ }
+
+ for ( i = 0; i < v_height / 2; ++i )
+ {
+ memcpy(dst_v_even, src_v_even, v_width);
+ memcpy(dst_v_odd, src_v_odd, v_width);
+
+ dst_v_even += 2 * v_width;
+ dst_v_odd += 2 * v_width;
+ src_v_even += 2 * v_stride;
+ src_v_odd += 2 * v_stride;
+ }
+
+ return 0;
+}
+
+int
+destridify(int width, int height, int fourcc, int stride,
+ const char * src, char * dst)
+{
+ /* NOTE: we're making-up the u and v strides for planar formats,
+ * rather than pass them in.
+ */
+
+ switch ( fourcc )
+ {
+ case VIDCAP_FOURCC_I420:
+ log_error("UNTESTED: destriding i420\n");
+ /* FIXME: only destride if necessary */
+ return destride_planar(width, height,
+ /* fix these u and v strides to be 32-bit aligned? */
+ width / 2, height / 2, width / 2, height / 2,
+ stride, stride / 2, stride / 2,
+ src, dst);
+ break;
+ case VIDCAP_FOURCC_YUY2:
+ if ( stride == 2 * width )
+ return -1;
+ return destride_packed(2 * width, height, stride, src, dst);
+ break;
+ case VIDCAP_FOURCC_RGB32:
+ if ( stride == 4 * width )
+ return -1;
+ return destride_packed(4 * width, height, stride, src, dst);
+ break;
+ case VIDCAP_FOURCC_2VUY:
+ if ( stride == 2 * width )
+ return -1;
+ return destride_packed(2 * width, height, stride, src, dst);
+ break;
+ case VIDCAP_FOURCC_RGB24:
+ if ( stride == 3 * width )
+ return -1;
+ return destride_packed(3 * width, height, stride, src, dst);
+ break;
+ case VIDCAP_FOURCC_BOTTOM_UP_RGB24:
+ if ( stride == 3 * width )
+ return -1;
+ return destride_packed(3 * width, height, stride, src, dst);
+ break;
+ case VIDCAP_FOURCC_YVU9:
+ log_error("UNTESTED: destriding yvu9\n");
+ /* FIXME: only destride if necessary */
+ return destride_planar(width, height,
+ width / 4, height / 4, width / 4, height / 4,
+ /* fix u and v strides to be 32-bit aligned? */
+ stride, stride / 4, stride / 4,
+ src, dst);
+ break;
+ default:
+ log_error("Invalid fourcc [%s]\n",
+ vidcap_fourcc_string_get(fourcc));
+ return -1;
+ break;
+ }
+}
+
conv_func
conv_conversion_func_get(int src_fourcc, int dst_fourcc)
{
Modified: trunk/src/conv.h
===================================================================
--- trunk/src/conv.h 2007-10-10 18:31:30 UTC (rev 45)
+++ trunk/src/conv.h 2007-10-12 16:30:09 UTC (rev 46)
@@ -53,6 +53,10 @@
const char *
conv_conversion_name_get(conv_func function);
+int
+destridify(int width, int height, int fourcc, int stride,
+ const char * src, char * dst);
+
#ifdef __cplusplus
}
#endif
Modified: trunk/src/directshow/SourceStateMachine.cpp
===================================================================
--- trunk/src/directshow/SourceStateMachine.cpp 2007-10-10 18:31:30 UTC (rev 45)
+++ trunk/src/directshow/SourceStateMachine.cpp 2007-10-12 16:30:09 UTC (rev 46)
@@ -367,7 +367,7 @@
okToSendStart_ = true;
// final capture callback - with error status
- sapi_src_capture_notify(sourceContext_, 0, 0, -1);
+ sapi_src_capture_notify(sourceContext_, 0, 0, 0, -1);
}
else
{
@@ -469,7 +469,7 @@
Sleep(10);
// final capture callback - with error status
- sapi_src_capture_notify(sourceContext_, 0, 0, -1);
+ sapi_src_capture_notify(sourceContext_, 0, 0, 0, -1);
}
}
@@ -496,7 +496,7 @@
src_->stop();
// final capture callback - with error status
- sapi_src_capture_notify(sourceContext_, 0, 0, -1);
+ sapi_src_capture_notify(sourceContext_, 0, 0, 0, -1);
callbackCancellationInProgress_ = false;
}
@@ -519,7 +519,7 @@
int ret = sapi_src_capture_notify(instance->sourceContext_,
reinterpret_cast<const char *>(pBuff),
- static_cast<int>(buffSize), 0);
+ static_cast<int>(buffSize), 0, 0);
instance->callbackInProgress_ = false;
Modified: trunk/src/sapi.c
===================================================================
--- trunk/src/sapi.c 2007-10-10 18:31:30 UTC (rev 45)
+++ trunk/src/sapi.c 2007-10-12 16:30:09 UTC (rev 46)
@@ -216,9 +216,11 @@
return 0;
}
+/* NOTE: stride-ignorant sapis should pass a stride of zero */
int
sapi_src_capture_notify(struct sapi_src_context * src_ctx,
const char * video_data, int video_data_size,
+ signed int stride,
int error_status)
{
struct vidcap_capture_info cap_info;
@@ -229,6 +231,8 @@
*/
vidcap_src_capture_callback cap_callback = src_ctx->capture_callback;
void * cap_data = src_ctx->capture_data;
+ void * buf = 0;
+ int buf_data_size = 0;
int send_frame = 0;
@@ -240,6 +244,23 @@
cap_info.error_status = error_status;
+ if ( !cap_info.error_status && stride &&
+ !destridify(src_ctx->fmt_native.width,
+ src_ctx->fmt_native.height,
+ src_ctx->fmt_native.fourcc,
+ stride,
+ video_data,
+ src_ctx->stride_free_buf) )
+ {
+ buf = src_ctx->stride_free_buf;
+ buf_data_size = src_ctx->stride_free_buf_size;
+ }
+ else
+ {
+ buf = (void *)video_data;
+ buf_data_size = video_data_size;
+ }
+
if ( cap_info.error_status )
{
cap_info.video_data = 0;
@@ -248,9 +269,9 @@
else if ( src_ctx->fmt_conv_func )
{
if ( src_ctx->fmt_conv_func(
- src_ctx->fmt_nominal.width,
- src_ctx->fmt_nominal.height,
- video_data,
+ src_ctx->fmt_native.width,
+ src_ctx->fmt_native.height,
+ buf,
src_ctx->fmt_conv_buf) )
{
log_error("failed format conversion\n");
@@ -262,8 +283,8 @@
}
else
{
- cap_info.video_data = video_data;
- cap_info.video_data_size = video_data_size;
+ cap_info.video_data = buf;
+ cap_info.video_data_size = buf_data_size;
}
if ( ( send_frame || error_status ) && cap_callback && cap_data != VIDCAP_INVALID_USER_DATA )
Modified: trunk/src/sapi.h
===================================================================
--- trunk/src/sapi.h 2007-10-10 18:31:30 UTC (rev 45)
+++ trunk/src/sapi.h 2007-10-12 16:30:09 UTC (rev 46)
@@ -47,6 +47,7 @@
int
sapi_src_capture_notify(struct sapi_src_context * src_ctx,
const char * video_data, int video_data_size,
+ signed int stride,
int error_status);
int
Modified: trunk/src/sapi_context.h
===================================================================
--- trunk/src/sapi_context.h 2007-10-10 18:31:30 UTC (rev 45)
+++ trunk/src/sapi_context.h 2007-10-12 16:30:09 UTC (rev 46)
@@ -71,6 +71,9 @@
char * fmt_conv_buf;
int fmt_conv_buf_size;
+ char * stride_free_buf;
+ int stride_free_buf_size;
+
struct vidcap_fmt_info * fmt_list;
int fmt_list_len;
Modified: trunk/src/sapi_qt.c
===================================================================
--- trunk/src/sapi_qt.c 2007-10-10 18:31:30 UTC (rev 45)
+++ trunk/src/sapi_qt.c 2007-10-12 16:30:09 UTC (rev 46)
@@ -215,7 +215,8 @@
sapi_src_capture_notify(src_ctx,
CVPixelBufferGetBaseAddress(pixel_buffer),
- CVPixelBufferGetDataSize(pixel_buffer), 0);
+ CVPixelBufferGetDataSize(pixel_buffer),
+ CVPixelBufferGetBytesPerRow(pixel_buffer), 0);
if ( (err = CVPixelBufferUnlockBaseAddress(pixel_buffer, 0)) )
{
@@ -425,7 +426,7 @@
if ( sg_source_capture_poll(qt_src_ctx->src) )
{
- sapi_src_capture_notify(src_ctx, 0, 0, -1);
+ sapi_src_capture_notify(src_ctx, 0, 0, 0, -1);
ret = -1;
goto bail;
}
Modified: trunk/src/sapi_v4l.c
===================================================================
--- trunk/src/sapi_v4l.c 2007-10-10 18:31:30 UTC (rev 45)
+++ trunk/src/sapi_v4l.c 2007-10-12 16:30:09 UTC (rev 46)
@@ -352,6 +352,7 @@
sapi_src_capture_notify(src_ctx, fb_base +
v4l_src_ctx->mbuf.offsets[capture_frame],
capture_size,
+ 0,
0);
++capture_frame_count;
Modified: trunk/src/vidcap.c
===================================================================
--- trunk/src/vidcap.c 2007-10-10 18:31:30 UTC (rev 45)
+++ trunk/src/vidcap.c 2007-10-12 16:30:09 UTC (rev 46)
@@ -356,6 +356,9 @@
if ( src_ctx->fmt_conv_buf )
free(src_ctx->fmt_conv_buf);
+ if ( src_ctx->stride_free_buf )
+ free(src_ctx->stride_free_buf);
+
if ( src_ctx->frame_times )
sliding_window_destroy(src_ctx->frame_times);
@@ -420,6 +423,32 @@
src_ctx->fmt_native.fourcc,
src_ctx->fmt_nominal.fourcc);
+ if ( src_ctx->stride_free_buf )
+ {
+ free(src_ctx->stride_free_buf);
+ src_ctx->stride_free_buf = 0;
+ }
+
+ src_ctx->stride_free_buf_size = conv_fmt_size_get(
+ src_ctx->fmt_native.width,
+ src_ctx->fmt_native.height,
+ src_ctx->fmt_native.fourcc);
+
+ if ( !src_ctx->stride_free_buf_size )
+ {
+ log_error("failed to get stride-free buffer size for %s\n",
+ vidcap_fourcc_string_get(
+ fmt_info->fourcc));
+ return -1;
+ }
+
+ if ( !(src_ctx->stride_free_buf =
+ malloc(src_ctx->stride_free_buf_size)) )
+ {
+ log_oom(__FILE__, __LINE__);
+ return -1;
+ }
+
if ( src_ctx->fmt_conv_buf )
{
free(src_ctx->fmt_conv_buf);
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: libvidcap c. m. <lib...@li...> - 2007-10-12 18:09:37
|
Revision: 47
http://libvidcap.svn.sourceforge.net/libvidcap/?rev=47&view=rev
Author: bcholew
Date: 2007-10-12 11:09:35 -0700 (Fri, 12 Oct 2007)
Log Message:
-----------
Add bottom-up rgb24 to conv_fmt_size_get(). Use proper fourcc in error message.
Modified Paths:
--------------
trunk/src/conv.c
trunk/src/vidcap.c
Modified: trunk/src/conv.c
===================================================================
--- trunk/src/conv.c 2007-10-12 16:30:09 UTC (rev 46)
+++ trunk/src/conv.c 2007-10-12 18:09:35 UTC (rev 47)
@@ -243,6 +243,7 @@
return pixels * 3 / 2;
case VIDCAP_FOURCC_RGB24:
+ case VIDCAP_FOURCC_BOTTOM_UP_RGB24:
return pixels * 3;
case VIDCAP_FOURCC_RGB32:
Modified: trunk/src/vidcap.c
===================================================================
--- trunk/src/vidcap.c 2007-10-12 16:30:09 UTC (rev 46)
+++ trunk/src/vidcap.c 2007-10-12 18:09:35 UTC (rev 47)
@@ -438,7 +438,7 @@
{
log_error("failed to get stride-free buffer size for %s\n",
vidcap_fourcc_string_get(
- fmt_info->fourcc));
+ src_ctx->fmt_native.fourcc));
return -1;
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: libvidcap c. m. <lib...@li...> - 2007-10-16 18:36:22
|
Revision: 48
http://libvidcap.svn.sourceforge.net/libvidcap/?rev=48&view=rev
Author: bcholew
Date: 2007-10-16 11:36:13 -0700 (Tue, 16 Oct 2007)
Log Message:
-----------
Handle failure to create new SourceStateMachine. Remove 'signed' modifier for stride.
Modified Paths:
--------------
trunk/src/conv.c
trunk/src/sapi.c
trunk/src/sapi.h
trunk/src/sapi_dshow.cpp
Modified: trunk/src/conv.c
===================================================================
--- trunk/src/conv.c 2007-10-12 18:09:35 UTC (rev 47)
+++ trunk/src/conv.c 2007-10-16 18:36:13 UTC (rev 48)
@@ -72,7 +72,7 @@
static const int conv_list_len = sizeof(conv_list) / sizeof(struct conv_info);
static int
-destride_packed(int image_byte_width, int height, signed int stride,
+destride_packed(int image_byte_width, int height, int stride,
const char * src, char * dst)
{
/* destride a packed structure */
@@ -100,7 +100,7 @@
destride_planar(int width, int height,
int u_width, int u_height,
int v_width, int v_height,
- signed int y_stride, signed int u_stride, signed int v_stride,
+ int y_stride, int u_stride, int v_stride,
const char * src, char * dst)
{
char * dst_y_even = dst;
Modified: trunk/src/sapi.c
===================================================================
--- trunk/src/sapi.c 2007-10-12 18:09:35 UTC (rev 47)
+++ trunk/src/sapi.c 2007-10-16 18:36:13 UTC (rev 48)
@@ -220,7 +220,7 @@
int
sapi_src_capture_notify(struct sapi_src_context * src_ctx,
const char * video_data, int video_data_size,
- signed int stride,
+ int stride,
int error_status)
{
struct vidcap_capture_info cap_info;
Modified: trunk/src/sapi.h
===================================================================
--- trunk/src/sapi.h 2007-10-12 18:09:35 UTC (rev 47)
+++ trunk/src/sapi.h 2007-10-16 18:36:13 UTC (rev 48)
@@ -47,7 +47,7 @@
int
sapi_src_capture_notify(struct sapi_src_context * src_ctx,
const char * video_data, int video_data_size,
- signed int stride,
+ int stride,
int error_status);
int
Modified: trunk/src/sapi_dshow.cpp
===================================================================
--- trunk/src/sapi_dshow.cpp 2007-10-12 18:09:35 UTC (rev 47)
+++ trunk/src/sapi_dshow.cpp 2007-10-16 18:36:13 UTC (rev 48)
@@ -177,6 +177,13 @@
return -1;
}
+ if ( src_ctx->priv == 0 )
+ {
+ log_warn("failed constructing source state machine for '%s'\n",
+ src_info->identifier);
+ return -1;
+ }
+
// Save acquired source to the dshow-specific source context
src_ctx->release = source_release;
src_ctx->format_validate = source_format_validate;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: libvidcap c. m. <lib...@li...> - 2007-10-16 19:00:03
|
Revision: 49
http://libvidcap.svn.sourceforge.net/libvidcap/?rev=49&view=rev
Author: bcholew
Date: 2007-10-16 11:59:56 -0700 (Tue, 16 Oct 2007)
Log Message:
-----------
Handle failure to create new DShowSrcManager.
Modified Paths:
--------------
trunk/src/directshow/GraphMonitor.cpp
trunk/src/sapi_dshow.cpp
Modified: trunk/src/directshow/GraphMonitor.cpp
===================================================================
--- trunk/src/directshow/GraphMonitor.cpp 2007-10-16 18:36:13 UTC (rev 48)
+++ trunk/src/directshow/GraphMonitor.cpp 2007-10-16 18:59:56 UTC (rev 49)
@@ -86,8 +86,6 @@
DWORD rc = WaitForSingleObject(initDoneEvent_, INFINITE);
- return;
-
}
GraphMonitor::~GraphMonitor()
Modified: trunk/src/sapi_dshow.cpp
===================================================================
--- trunk/src/sapi_dshow.cpp 2007-10-16 18:36:13 UTC (rev 48)
+++ trunk/src/sapi_dshow.cpp 2007-10-16 18:59:56 UTC (rev 49)
@@ -214,6 +214,12 @@
return -1;
}
+ if ( sapi_ctx->priv == 0 )
+ {
+ log_error("failed constructing DShowSrcManager\n");
+ return -1;
+ }
+
sapi_ctx->identifier = identifier;
sapi_ctx->description = description;
sapi_ctx->acquire = sapi_acquire;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: libvidcap c. <lib...@li...> - 2007-11-02 21:13:23
|
Revision: 63
http://libvidcap.svn.sourceforge.net/libvidcap/?rev=63&view=rev
Author: bcholew
Date: 2007-11-02 14:13:19 -0700 (Fri, 02 Nov 2007)
Log Message:
-----------
Don't allow source release while capturing. Flag future fix.
Modified Paths:
--------------
trunk/src/sapi.c
trunk/src/vidcap.c
Modified: trunk/src/sapi.c
===================================================================
--- trunk/src/sapi.c 2007-11-01 19:05:34 UTC (rev 62)
+++ trunk/src/sapi.c 2007-11-02 21:13:19 UTC (rev 63)
@@ -287,8 +287,12 @@
cap_info.video_data_size = buf_data_size;
}
- if ( ( send_frame || error_status ) && cap_callback && cap_data != VIDCAP_INVALID_USER_DATA )
+ if ( ( send_frame || error_status ) && cap_callback &&
+ cap_data != VIDCAP_INVALID_USER_DATA )
{
+ /* FIXME: Need to check return code.
+ * Application may want capture to stop
+ */
cap_callback(src_ctx, cap_data, &cap_info);
if ( cap_info.error_status )
Modified: trunk/src/vidcap.c
===================================================================
--- trunk/src/vidcap.c 2007-11-01 19:05:34 UTC (rev 62)
+++ trunk/src/vidcap.c 2007-11-02 21:13:19 UTC (rev 63)
@@ -349,6 +349,9 @@
struct sapi_src_context * src_ctx = (struct sapi_src_context *)src;
int ret;
+ if ( src_ctx->src_state == src_capturing )
+ return -1;
+
ret = src_ctx->release(src_ctx);
if ( src_ctx->fmt_list_len )
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: libvidcap c. <lib...@li...> - 2007-12-03 14:09:10
|
Revision: 72
http://libvidcap.svn.sourceforge.net/libvidcap/?rev=72&view=rev
Author: bcholew
Date: 2007-12-03 06:09:08 -0800 (Mon, 03 Dec 2007)
Log Message:
-----------
Use abstracted thread and mutex functions in v4l and qt sapis.
Modified Paths:
--------------
trunk/src/sapi_qt.c
trunk/src/sapi_v4l.c
Modified: trunk/src/sapi_qt.c
===================================================================
--- trunk/src/sapi_qt.c 2007-12-03 14:07:46 UTC (rev 71)
+++ trunk/src/sapi_qt.c 2007-12-03 14:09:08 UTC (rev 72)
@@ -23,7 +23,6 @@
*
*/
-#include <pthread.h>
#include <stdlib.h>
#include <strings.h>
@@ -40,8 +39,9 @@
struct sapi_qt_context
{
- pthread_mutex_t mutex;
- pthread_t notify_thread;
+ vc_mutex mutex;
+ vc_thread notify_thread;
+ unsigned int notify_thread_id;
int notifying;
struct sg_manager mgr;
@@ -52,7 +52,8 @@
struct sg_source * src;
int capturing;
- pthread_t capture_thread;
+ vc_thread capture_thread;
+ unsigned int capture_thread_id;
TimeValue last_time;
long frame_count;
@@ -61,20 +62,20 @@
};
static int
-mutex_lock(pthread_mutex_t * mutex)
+mutex_lock(vc_mutex * mutex)
{
- int err = pthread_mutex_lock(mutex);
+ int err = vc_mutex_lock(mutex);
if ( err )
- log_error("failed pthread_mutex_lock() %d\n", err);
+ log_error("failed vc_mutex_lock() %d\n", err);
return err;
}
static int
-mutex_unlock(pthread_mutex_t * mutex)
+mutex_unlock(vc_mutex * mutex)
{
- int err = pthread_mutex_unlock(mutex);
+ int err = vc_mutex_unlock(mutex);
if ( err )
- log_error("failed pthread_mutex_unlock() %d\n", err);
+ log_error("failed vc_mutex_unlock() %d\n", err);
return err;
}
@@ -372,7 +373,7 @@
return ts;
}
-static void *
+static unsigned int
capture_thread_proc(void * data)
{
struct sapi_src_context * src_ctx =
@@ -392,22 +393,32 @@
if ( map_fourcc_to_ostype(src_ctx->fmt_native.fourcc, &pixel_format) )
{
- log_error("invalid pixel format '%s'\n",
+ log_error("invalid pixel format '%s' (0x%0x)\n",
vidcap_fourcc_string_get(
- src_ctx->fmt_native.fourcc));
- return (void *)-1;
+ src_ctx->fmt_native.fourcc),
+ src_ctx->fmt_native.fourcc);
+
+ ret = -2;
+ sapi_src_capture_notify(src_ctx, 0, 0, 0, ret);
+ return ret;
}
if ( sg_source_format_set(qt_src_ctx->src,
src_ctx->fmt_native.width,
src_ctx->fmt_native.height,
fps, pixel_format) )
- return (void *)-1;
+ {
+ ret = -3;
+ sapi_src_capture_notify(src_ctx, 0, 0, 0, ret);
+ return ret;
+ }
if ( qt_src_ctx->decomp_session )
{
log_error("decomp session already setup\n");
- return (void *)-1;
+ ret = -4;
+ sapi_src_capture_notify(src_ctx, 0, 0, 0, ret);
+ return ret;
}
qt_src_ctx->last_time = 0;
@@ -415,10 +426,18 @@
if ( sg_source_capture_start(qt_src_ctx->src, source_capture_callback,
(long)src_ctx) )
- return (void *)-1;
+ {
+ ret = -5;
+ sapi_src_capture_notify(src_ctx, 0, 0, 0, ret);
+ return ret;
+ }
if ( source_decomp_session_setup(src_ctx) )
- return (void *)-1;
+ {
+ ret = -6;
+ sapi_src_capture_notify(src_ctx, 0, 0, 0, ret);
+ return ret;
+ }
while ( qt_src_ctx->capturing )
{
@@ -426,8 +445,8 @@
if ( sg_source_capture_poll(qt_src_ctx->src) )
{
- sapi_src_capture_notify(src_ctx, 0, 0, 0, -1);
- ret = -1;
+ ret = -7;
+ sapi_src_capture_notify(src_ctx, 0, 0, 0, ret);
goto bail;
}
@@ -436,8 +455,9 @@
if ( errno != -EINTR )
{
log_error("failed nanosleep() %d\n", errno);
- ret = -1;
- goto bail;
+ ret = -8;
+ sapi_src_capture_notify(src_ctx, 0, 0, 0, ret);
+ goto bail;
}
}
}
@@ -445,12 +465,12 @@
bail:
if ( source_decomp_session_takedown(src_ctx) )
- ret = -1;
+ ret -= 100;
if ( sg_source_capture_stop(qt_src_ctx->src) )
- ret = -1;
+ ret -= -1000;
- return (void *)ret;
+ return ret;
}
static int
@@ -462,10 +482,11 @@
qt_src_ctx->capturing = 1;
- if ( (ret = pthread_create(&qt_src_ctx->capture_thread, 0,
- capture_thread_proc, src_ctx)) )
+ if ( (ret = vc_create_thread(&qt_src_ctx->capture_thread,
+ capture_thread_proc,
+ src_ctx, &qt_src_ctx->capture_thread_id)) )
{
- log_error("failed pthread_create() for capture thread %d\n",
+ log_error("failed vc_thread_create() for capture thread %d\n",
ret);
return -1;
}
@@ -480,20 +501,15 @@
(struct sapi_qt_src_context *)src_ctx->priv;
int ret;
- int thread_ret;
qt_src_ctx->capturing = 0;
- if ( (ret = pthread_join(qt_src_ctx->capture_thread,
- (void *)&thread_ret)) )
+ if ( (ret = vc_thread_join(&qt_src_ctx->capture_thread)) )
{
- log_error("failed pthread_join() %d\n", ret);
+ log_error("failed vc_thread_join() %d\n", ret);
return -1;
}
- if ( thread_ret )
- log_warn("capture_thread_proc returned %d\n", thread_ret);
-
return 0;
}
@@ -674,7 +690,7 @@
return -1;
}
-static void *
+static unsigned int
notify_thread_proc(void * data)
{
struct sapi_context * sapi_ctx = (struct sapi_context *)data;
@@ -690,18 +706,18 @@
int source_count;
if ( mutex_lock(&qt_ctx->mutex) )
- return (void *)-1;
+ return -1;
if ( sg_manager_update(&qt_ctx->mgr) )
{
mutex_unlock(&qt_ctx->mutex);
- return (void *)-1;
+ return -1;
}
source_count = sg_manager_source_count(&qt_ctx->mgr);
if ( mutex_unlock(&qt_ctx->mutex) )
- return (void *)-1;
+ return -1;
if ( source_count != last_source_count &&
sapi_ctx->notify_callback )
@@ -716,7 +732,7 @@
if ( errno != -EINTR )
{
log_error("failed nanosleep() %d\n", errno);
- return (void *)-1;
+ return -1;
}
}
}
@@ -729,20 +745,16 @@
{
struct sapi_qt_context * qt_ctx =
(struct sapi_qt_context *)sapi_ctx->priv;
- int thread_ret;
int ret;
qt_ctx->notifying = 0;
- if ( (ret = pthread_join(qt_ctx->notify_thread, (void *)&thread_ret)) )
+ if ( (ret = vc_thread_join(&qt_ctx->notify_thread)) )
{
- log_error("failed pthread_join() notify thread %d\n", ret);
+ log_error("failed vc_thread_join() notify thread %d\n", ret);
return -1;
}
- if ( thread_ret )
- log_warn("notify_thread_proc returned %d\n", thread_ret);
-
return 0;
}
@@ -758,10 +770,10 @@
qt_ctx->notifying = 1;
- if ( (ret = pthread_create(&qt_ctx->notify_thread, 0,
- notify_thread_proc, sapi_ctx)) )
+ if ( (ret = vc_create_thread(&qt_ctx->notify_thread, notify_thread_proc,
+ sapi_ctx, &qt_ctx->notify_thread_id)) )
{
- log_error("failed pthread_create() for notify thread %d\n",
+ log_error("failed vc_thread_create() for notify thread %d\n",
ret);
return -1;
}
@@ -791,7 +803,7 @@
ExitMovies();
- pthread_mutex_destroy(&qt_ctx->mutex);
+ vc_mutex_destroy(&qt_ctx->mutex);
free(sapi_ctx->user_src_list.list);
free(qt_ctx);
@@ -810,9 +822,9 @@
return -1;
}
- if ( pthread_mutex_init(&qt_ctx->mutex, 0) )
+ if ( vc_mutex_init(&qt_ctx->mutex) )
{
- log_error("failed pthread_mutex_init()\n");
+ log_error("failed vc_mutex_init()\n");
return -1;
}
Modified: trunk/src/sapi_v4l.c
===================================================================
--- trunk/src/sapi_v4l.c 2007-12-03 14:07:46 UTC (rev 71)
+++ trunk/src/sapi_v4l.c 2007-12-03 14:09:08 UTC (rev 72)
@@ -26,7 +26,6 @@
#include <errno.h>
#include <fcntl.h>
#include <linux/videodev.h>
-#include <pthread.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
@@ -51,8 +50,9 @@
struct sapi_v4l_context
{
- pthread_mutex_t mutex;
- pthread_t notify_thread;
+ vc_mutex mutex;
+ vc_thread notify_thread;
+ unsigned int notify_thread_id;
int notifying;
struct sapi_src_list acquired_src_list;
};
@@ -71,7 +71,8 @@
struct video_mbuf mbuf;
int capturing;
- pthread_t capture_thread;
+ vc_thread capture_thread;
+ unsigned int capture_thread_id;
};
static int
@@ -533,7 +534,7 @@
return 0;
}
-static void *
+static unsigned int
capture_thread_proc(void * data)
{
struct sapi_src_context * src_ctx =
@@ -554,7 +555,7 @@
if ( fb_base == (void *)-1 )
{
log_error("failed mmap() %d\n", errno);
- return (void *)-1;
+ return -1;
}
if ( capture_kickoff(src_ctx, started_frame_count) )
@@ -575,8 +576,8 @@
goto bail;
}
- sapi_src_capture_notify(src_ctx, fb_base +
- v4l_src_ctx->mbuf.offsets[capture_frame],
+ sapi_src_capture_notify(src_ctx, (char *)(fb_base +
+ v4l_src_ctx->mbuf.offsets[capture_frame]),
capture_size,
0,
0);
@@ -603,7 +604,7 @@
if ( munmap((void *)fb_base, v4l_src_ctx->mbuf.size) == -1 )
{
log_error("failed munmap() %d\n", errno);
- return (void *)-1;
+ return -1;
}
return 0;
@@ -612,7 +613,7 @@
if ( munmap((void *)fb_base, v4l_src_ctx->mbuf.size) == -1 )
log_warn("failed munmap() %d\n", errno);
- return (void *)-1;
+ return -1;
}
static int
@@ -624,10 +625,11 @@
v4l_src_ctx->capturing = 1;
- if ( (ret = pthread_create(&v4l_src_ctx->capture_thread, 0,
- capture_thread_proc, src_ctx)) )
+ if ( (ret = vc_create_thread(&v4l_src_ctx->capture_thread,
+ capture_thread_proc, src_ctx,
+ &v4l_src_ctx->capture_thread_id)) )
{
- log_error("failed pthread_create() for capture thread %d\n",
+ log_error("failed vc_create_thread() for capture thread %d\n",
ret);
return -1;
}
@@ -641,20 +643,15 @@
struct sapi_v4l_src_context * v4l_src_ctx =
(struct sapi_v4l_src_context *)src_ctx->priv;
int ret;
- int thread_ret;
v4l_src_ctx->capturing = 0;
- if ( (ret = pthread_join(v4l_src_ctx->capture_thread,
- (void *)&thread_ret)) )
+ if ( (ret = vc_thread_join(&v4l_src_ctx->capture_thread)) )
{
- log_error("failed pthread_join() %d\n", ret);
+ log_error("failed vc_thread_join() %d\n", ret);
return -1;
}
- if ( thread_ret )
- log_warn("capture_thread_proc returned %d\n", thread_ret);
-
return 0;
}
@@ -928,7 +925,7 @@
return -1;
}
-static void *
+static unsigned int
notify_thread_proc(void * data)
{
struct sapi_context * sapi_ctx = (struct sapi_context *)data;
@@ -939,18 +936,18 @@
while ( v4l_ctx->notifying )
{
- pthread_mutex_lock(&v4l_ctx->mutex);
+ vc_mutex_lock(&v4l_ctx->mutex);
/* TODO: look for devices */
- pthread_mutex_unlock(&v4l_ctx->mutex);
+ vc_mutex_unlock(&v4l_ctx->mutex);
if ( nanosleep(&wait_ts, 0) )
{
if ( errno != -EINTR )
{
log_error("failed nanosleep() %d\n", errno);
- return (void *)-1;
+ return -1;
}
}
}
@@ -963,20 +960,16 @@
{
struct sapi_v4l_context * v4l_ctx =
(struct sapi_v4l_context *)sapi_ctx->priv;
- int thread_ret;
int ret;
v4l_ctx->notifying = 0;
- if ( (ret = pthread_join(v4l_ctx->notify_thread, (void *)&thread_ret)) )
+ if ( (ret = vc_thread_join(&v4l_ctx->notify_thread)) )
{
- log_error("failed pthread_join() notify thread %d\n", ret);
+ log_error("failed vc_thread_join() notify thread %d\n", ret);
return -1;
}
- if ( thread_ret )
- log_warn("notify_thread_proc returned %d\n", thread_ret);
-
return 0;
}
@@ -992,10 +985,11 @@
v4l_ctx->notifying = 1;
- if ( (ret = pthread_create(&v4l_ctx->notify_thread, 0,
- notify_thread_proc, sapi_ctx)) )
+ if ( (ret = vc_create_thread(&v4l_ctx->notify_thread,
+ notify_thread_proc, sapi_ctx,
+ &v4l_ctx->notify_thread_id)) )
{
- log_error("failed pthread_create() for notify thread %d\n",
+ log_error("failed vc_create_thread() for notify thread %d\n",
ret);
return -1;
}
@@ -1009,7 +1003,7 @@
struct sapi_v4l_context * v4l_ctx =
(struct sapi_v4l_context *)sapi_ctx->priv;
- pthread_mutex_destroy(&v4l_ctx->mutex);
+ vc_mutex_destroy(&v4l_ctx->mutex);
free(sapi_ctx->user_src_list.list);
free(v4l_ctx);
@@ -1028,9 +1022,9 @@
return -1;
}
- if ( pthread_mutex_init(&v4l_ctx->mutex, 0) )
+ if ( vc_mutex_init(&v4l_ctx->mutex) )
{
- log_error("failed pthread_mutex_init()\n");
+ log_error("failed vc_mutex_init()\n");
return -1;
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: libvidcap c. <lib...@li...> - 2007-12-04 19:24:18
|
Revision: 78
http://libvidcap.svn.sourceforge.net/libvidcap/?rev=78&view=rev
Author: bcholew
Date: 2007-12-04 11:24:16 -0800 (Tue, 04 Dec 2007)
Log Message:
-----------
Change execute permissions.
Property Changed:
----------------
trunk/src/double_buffer.c
trunk/src/double_buffer.h
trunk/src/os_funcs.h
Property changes on: trunk/src/double_buffer.c
___________________________________________________________________
Name: svn:executable
- *
Property changes on: trunk/src/double_buffer.h
___________________________________________________________________
Name: svn:executable
- *
Property changes on: trunk/src/os_funcs.h
___________________________________________________________________
Name: svn:executable
- *
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|