You can subscribe to this list here.
2007 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
(32) |
Oct
(26) |
Nov
(8) |
Dec
(17) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2008 |
Jan
|
Feb
|
Mar
|
Apr
(8) |
May
|
Jun
(1) |
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2009 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
(1) |
Sep
(2) |
Oct
(1) |
Nov
|
Dec
|
2010 |
Jan
|
Feb
(5) |
Mar
(2) |
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: libvidcap c. m. <lib...@li...> - 2007-09-26 13:50:42
|
Revision: 31 http://libvidcap.svn.sourceforge.net/libvidcap/?rev=31&view=rev Author: bcholew Date: 2007-09-26 06:50:10 -0700 (Wed, 26 Sep 2007) Log Message: ----------- Add function to convert from rgb32 to i420. Modified Paths: -------------- trunk/src/conv_to_i420.c Modified: trunk/src/conv_to_i420.c =================================================================== --- trunk/src/conv_to_i420.c 2007-09-25 13:15:23 UTC (rev 30) +++ trunk/src/conv_to_i420.c 2007-09-26 13:50:10 UTC (rev 31) @@ -30,11 +30,66 @@ /* NOTE: size of dest must be >= width * height * 3 / 2 */ +/* Based on formulas found at http://en.wikipedia.org/wiki/YUV */ int vidcap_rgb32_to_i420(int width, int height, const char * src, char * dst) { - log_error("vidcap_rgb32_to_i420() not implemented\n"); - return -1; + unsigned char * dst_y_even; + unsigned char * dst_y_odd; + unsigned char * dst_u; + unsigned char * dst_v; + const unsigned char *src_even; + const unsigned char *src_odd; + int i, j; + + src_even = (const unsigned char *)src; + src_odd = src_even + width * 4; + + dst_y_even = (unsigned char *)dst; + dst_y_odd = dst_y_even + width; + dst_u = dst_y_even + width * height; + dst_v = dst_u + ((width * height) >> 2); + + for ( i = 0; i < height / 2; ++i ) + { + for ( j = 0; j < width / 2; ++j ) + { + short r, g, b; + b = *src_even++; + g = *src_even++; + r = *src_even++; + ++src_even; + *dst_y_even++ = (( r * 66 + g * 129 + b * 25 + 128 ) >> 8 ) + 16; + + *dst_u++ = (( r * -38 - g * 74 + b * 112 + 128 ) >> 8 ) + 128; + *dst_v++ = (( r * 112 - g * 94 - b * 18 + 128 ) >> 8 ) + 128; + + b = *src_even++; + g = *src_even++; + r = *src_even++; + ++src_even; + *dst_y_even++ = (( r * 66 + g * 129 + b * 25 + 128 ) >> 8 ) + 16; + + b = *src_odd++; + g = *src_odd++; + r = *src_odd++; + ++src_odd; + *dst_y_odd++ = (( r * 66 + g * 129 + b * 25 + 128 ) >> 8 ) + 16; + + b = *src_odd++; + g = *src_odd++; + r = *src_odd++; + ++src_odd; + *dst_y_odd++ = (( r * 66 + g * 129 + b * 25 + 128 ) >> 8 ) + 16; + } + + dst_y_even += width; + dst_y_odd += width; + 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-09-25 13:15:27
|
Revision: 30 http://libvidcap.svn.sourceforge.net/libvidcap/?rev=30&view=rev Author: bcholew Date: 2007-09-25 06:15:23 -0700 (Tue, 25 Sep 2007) Log Message: ----------- Add function to convert from i420 to yuy2. Modified Paths: -------------- trunk/src/conv_to_yuy2.c Modified: trunk/src/conv_to_yuy2.c =================================================================== --- trunk/src/conv_to_yuy2.c 2007-09-24 18:49:27 UTC (rev 29) +++ trunk/src/conv_to_yuy2.c 2007-09-25 13:15:23 UTC (rev 30) @@ -38,8 +38,44 @@ int vidcap_i420_to_yuy2(int width, int height, const char * src, char * dest) { - log_error("vidcap_i420_to_yuy2() not implemented\n"); - return -1; + /* convert from a planar structure to a packed structure */ + const char * src_y_even = src; + const char * src_y_odd = src + width; + const char * src_u = src + width * height; + const char * src_v = src_u + width * height / 4; + char * dst_even = dest; + char * dst_odd = dest + width * 2; + + int i, j; + + /* i420 has a vertical sampling period (for u and v) + * double that for yuy2. Will re-use + * U and V data during repackaging. + */ + for ( i = 0; i < height / 2; ++i ) + { + for ( j = 0; j < width / 2; ++j ) + { + *dst_even++ = *src_y_even++; + *dst_odd++ = *src_y_odd++; + + *dst_even++ = *src_u; + *dst_odd++ = *src_u++; + + *dst_even++ = *src_y_even++; + *dst_odd++ = *src_y_odd++; + + *dst_even++ = *src_v; + *dst_odd++ = *src_v++; + } + + src_y_even += width; + src_y_odd += width; + dst_even += width * 2; + dst_odd += width * 2; + } + + 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-09-24 18:50:14
|
Revision: 29 http://libvidcap.svn.sourceforge.net/libvidcap/?rev=29&view=rev Author: bcholew Date: 2007-09-24 11:49:27 -0700 (Mon, 24 Sep 2007) Log Message: ----------- Only clear graphIsSetup_ flag if RemoveFilter() succeeds. If couldn't remove sample grabber because graph wasn't actually stopped, send the stop request. This could happen in cases of rapid start/stop requests. Modified Paths: -------------- trunk/src/directshow/DirectShowSource.cpp Modified: trunk/src/directshow/DirectShowSource.cpp =================================================================== --- trunk/src/directshow/DirectShowSource.cpp 2007-09-24 12:38:15 UTC (rev 28) +++ trunk/src/directshow/DirectShowSource.cpp 2007-09-24 18:49:27 UTC (rev 29) @@ -485,16 +485,26 @@ { if ( graphIsSetup_ ) { - graphIsSetup_ = false; - // necessary to allow subsequent calls to RenderStream() // (like after rebinding) to succeed HRESULT hr = pFilterGraph_->RemoveFilter(pSampleGrabber_); if ( FAILED(hr) ) { log_error("failed to remove Sample Grabber (%d)\n", hr); + if ( hr == VFW_E_NOT_STOPPED ) + { + log_error("Capture wasn't stopped. " + "Repeating STOP request...\n"); + stop(); + } + else + { + log_error("not processing removal failure\n"); + } return 1; } + + graphIsSetup_ = false; } 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-24 12:38:18
|
Revision: 28 http://libvidcap.svn.sourceforge.net/libvidcap/?rev=28&view=rev Author: jpgrayson Date: 2007-09-24 05:38:15 -0700 (Mon, 24 Sep 2007) Log Message: ----------- Reorder some macros for mac autogen.sh compatibility. Modified Paths: -------------- trunk/configure.ac Modified: trunk/configure.ac =================================================================== --- trunk/configure.ac 2007-09-22 04:09:14 UTC (rev 27) +++ trunk/configure.ac 2007-09-24 12:38:15 UTC (rev 28) @@ -25,8 +25,8 @@ AC_GNU_SOURCE AC_PROG_CC +AM_PROG_CC_STDC AM_PROG_CC_C_O -AM_PROG_CC_STDC AC_C_CONST AC_PROG_GCC_TRADITIONAL AC_PROG_CXX 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-22 04:09:16
|
Revision: 27 http://libvidcap.svn.sourceforge.net/libvidcap/?rev=27&view=rev Author: bcholew Date: 2007-09-21 21:09:14 -0700 (Fri, 21 Sep 2007) Log Message: ----------- Release source context before freeing it's members. Modified Paths: -------------- trunk/src/vidcap.c Modified: trunk/src/vidcap.c =================================================================== --- trunk/src/vidcap.c 2007-09-20 17:51:50 UTC (rev 26) +++ trunk/src/vidcap.c 2007-09-22 04:09:14 UTC (rev 27) @@ -318,14 +318,14 @@ struct sapi_src_context * src_ctx = (struct sapi_src_context *)src; int ret; + ret = src_ctx->release(src_ctx); + if ( src_ctx->fmt_list_len ) free(src_ctx->fmt_list); if ( src_ctx->fmt_conv_buf ) free(src_ctx->fmt_conv_buf); - ret = src_ctx->release(src_ctx); - free(src_ctx); 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-20 17:51:52
|
Revision: 26 http://libvidcap.svn.sourceforge.net/libvidcap/?rev=26&view=rev Author: bcholew Date: 2007-09-20 10:51:50 -0700 (Thu, 20 Sep 2007) Log Message: ----------- ove AddFilter() of pSource_ and pNullRenderer to construction time. This simplifies the code, and has the added benefit of reducing the memory leak that exists when using the MS LifeCam NX-6000 in scenarios that re-bind a source. Move setting of pStreamConfig_'s format from bind time (in main thread) to capture start time (in source thread). This keeps the main thread running smoothly if/when this operation blocks for a while. Return failure at bind time if we fail to remove the sample grabber from the filter graph. Rename a flag. Modified Paths: -------------- trunk/src/directshow/DirectShowSource.cpp trunk/src/directshow/DirectShowSource.h Modified: trunk/src/directshow/DirectShowSource.cpp =================================================================== --- trunk/src/directshow/DirectShowSource.cpp 2007-09-18 18:38:47 UTC (rev 25) +++ trunk/src/directshow/DirectShowSource.cpp 2007-09-20 17:51:50 UTC (rev 26) @@ -51,7 +51,7 @@ pNullRenderer_(0), pMediaControlIF_(0), nativeMediaType_(0), - captureIsSetup_(false), + graphIsSetup_(false), eventInitDone_(0), eventStart_(0), eventStop_(0), @@ -287,6 +287,20 @@ return -1; } + hr = pFilterGraph_->AddFilter(pSource_, L"Source Device"); + if ( FAILED(hr) ) + { + log_error("failed to add source (%d)\n", hr); + return -1; + } + + hr = pFilterGraph_->AddFilter(pNullRenderer_, L"NullRenderer"); + if ( FAILED(hr) ) + { + log_error("failed to add null renderer (%d)\n", hr); + return -1; + } + return 0; } @@ -466,47 +480,45 @@ return 0; } -void +int DirectShowSource::resetCapGraphFoo() { - if ( captureIsSetup_ ) + if ( graphIsSetup_ ) { - // some or all of this appears to be necessary to allow - // subsequent captures with a different media type - HRESULT hr = pFilterGraph_->RemoveFilter(pSource_); - if ( FAILED(hr) ) - log_error("failed to remove source (%d)\n", hr); + graphIsSetup_ = false; - hr = pFilterGraph_->RemoveFilter(pSampleGrabber_); + // necessary to allow subsequent calls to RenderStream() + // (like after rebinding) to succeed + HRESULT hr = pFilterGraph_->RemoveFilter(pSampleGrabber_); if ( FAILED(hr) ) - log_error("failed to remove Sample Grabber (%d)\n", - hr); - - hr = pFilterGraph_->RemoveFilter(pNullRenderer_); - if ( FAILED(hr) ) - log_error("failed to remove null renderer (%d)\n", hr); - - captureIsSetup_ = false; + { + log_error("failed to remove Sample Grabber (%d)\n", hr); + return 1; + } } + + return 0; } int DirectShowSource::setupCapGraphFoo() { - if ( !captureIsSetup_ ) + if ( !graphIsSetup_ ) { - // Set sample grabber's media type to match that of the source - HRESULT hr = pSampleGrabberIF_->SetMediaType(nativeMediaType_); + // set the stream's media type + HRESULT hr = pStreamConfig_->SetFormat(nativeMediaType_); if ( FAILED(hr) ) { - log_error("failed to set grabber media type (%d)\n", hr); + log_error("failed setting stream format (%d)\n", hr); + return -1; } - hr = pFilterGraph_->AddFilter(pSource_, L"Source Device"); + // Set sample grabber's media type + hr = pSampleGrabberIF_->SetMediaType(nativeMediaType_); if ( FAILED(hr) ) { - log_error("failed to add source (%d)\n", hr); + log_error("failed to set grabber media type (%d)\n", hr); return -1; } @@ -517,13 +529,6 @@ return -1; } - hr = pFilterGraph_->AddFilter(pNullRenderer_, L"NullRenderer"); - if ( FAILED(hr) ) - { - log_error("failed to add null renderer (%d)\n", hr); - return -1; - } - hr = pCapGraphBuilder_->RenderStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, pSource_, @@ -536,7 +541,7 @@ return -1; } - captureIsSetup_ = true; + graphIsSetup_ = true; } return 0; @@ -577,7 +582,6 @@ if ( !setupCapGraphFoo() ) { HRESULT hr = pMediaControlIF_->Run(); - if ( SUCCEEDED(hr) ) return; else @@ -593,7 +597,7 @@ int DirectShowSource::stop() { - // signal to source thread to stop capturing + // signal to source thread to stop capturing if ( !SetEvent(eventStop_) ) { log_error("failed to signal source to stop (%d)\n", @@ -607,7 +611,7 @@ void DirectShowSource::doStop() { - if ( captureIsSetup_ ) + if ( graphIsSetup_ ) { HRESULT hr = pMediaControlIF_->Stop(); if ( FAILED(hr) ) @@ -655,21 +659,7 @@ vih->bmiHeader.biWidth = fmtNative.width; vih->bmiHeader.biHeight = fmtNative.height; - resetCapGraphFoo(); - - // set the stream's media type - HRESULT hr = pStreamConfig_->SetFormat(nativeMediaType_); - if ( FAILED(hr) ) - { - log_error("failed setting stream format (%d)\n", hr); - - freeMediaType(*nativeMediaType_); - nativeMediaType_ = 0; - - return 1; - } - - return 0; + return resetCapGraphFoo(); } bool Modified: trunk/src/directshow/DirectShowSource.h =================================================================== --- trunk/src/directshow/DirectShowSource.h 2007-09-18 18:38:47 UTC (rev 25) +++ trunk/src/directshow/DirectShowSource.h 2007-09-20 17:51:50 UTC (rev 26) @@ -62,7 +62,7 @@ int createCapGraphFoo(); void destroyCapGraphFoo(); int setupCapGraphFoo(); - void resetCapGraphFoo(); + int resetCapGraphFoo(); bool checkFormat(const vidcap_fmt_info * fmtNominal, vidcap_fmt_info * fmtNative, int formatNum, @@ -104,7 +104,7 @@ IBaseFilter * pNullRenderer_; IMediaControl * pMediaControlIF_; AM_MEDIA_TYPE *nativeMediaType_; - bool captureIsSetup_; + bool graphIsSetup_; HANDLE eventInitDone_; HANDLE eventStart_; 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:39:04
|
Revision: 25 http://libvidcap.svn.sourceforge.net/libvidcap/?rev=25&view=rev Author: bcholew Date: 2007-09-18 11:38:47 -0700 (Tue, 18 Sep 2007) Log Message: ----------- oops Modified Paths: -------------- trunk/src/directshow/DirectShowSource.cpp Modified: trunk/src/directshow/DirectShowSource.cpp =================================================================== --- trunk/src/directshow/DirectShowSource.cpp 2007-09-18 18:36:50 UTC (rev 24) +++ trunk/src/directshow/DirectShowSource.cpp 2007-09-18 18:38:47 UTC (rev 25) @@ -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-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-18 17:15:04
|
Revision: 23 http://libvidcap.svn.sourceforge.net/libvidcap/?rev=23&view=rev Author: bcholew Date: 2007-09-18 10:14:56 -0700 (Tue, 18 Sep 2007) Log Message: ----------- Move setup of sampleGrabber_, pSampleGrabberIF_, nullRenderer_ to construction time. Consolidate most of the capture graph tinkering to four functions. Allow subsequent captures with different formats to succeed - by removing filters from capture graph when resetting capture graph foo. Rename and move some functions. Modified Paths: -------------- trunk/src/directshow/DirectShowSource.cpp trunk/src/directshow/DirectShowSource.h Modified: trunk/src/directshow/DirectShowSource.cpp =================================================================== --- trunk/src/directshow/DirectShowSource.cpp 2007-09-17 18:57:01 UTC (rev 22) +++ trunk/src/directshow/DirectShowSource.cpp 2007-09-18 17:14:56 UTC (rev 23) @@ -97,65 +97,9 @@ goto constructionFailure; } - hr = CoCreateInstance(CLSID_CaptureGraphBuilder2, - NULL, - CLSCTX_INPROC_SERVER, - IID_ICaptureGraphBuilder2, - (void **)&pCapGraphBuilder_); - - if ( FAILED(hr) ) - { - log_error("failed creating capture graph builder (%d)\n", hr); + if ( createCapGraphFoo() ) goto constructionFailure; - } - hr = pCapGraphBuilder_->FindInterface(&PIN_CATEGORY_CAPTURE, - &MEDIATYPE_Video, - pSource_, - IID_IAMStreamConfig, - (void **)&pStreamConfig_); - if( FAILED(hr) ) - { - log_error("failed getting stream config " - "while building format list (%d)\n", hr); - pCapGraphBuilder_->Release(); - goto constructionFailure; - } - - hr = CoCreateInstance(CLSID_FilterGraph, - 0, - CLSCTX_INPROC_SERVER, - IID_IGraphBuilder, - (void **)&pFilterGraph_); - if ( FAILED(hr) ) - { - log_error("failed creating the filter graph (%d)\n", hr); - goto constructionFailure; - } - - hr = pCapGraphBuilder_->SetFiltergraph(pFilterGraph_); - if ( FAILED(hr) ) - { - log_error("failed setting the filter graph (%d)\n", hr); - goto constructionFailure; - } - - hr = pFilterGraph_->QueryInterface(IID_IMediaEventEx, - (void **)&pMediaEventIF_); - if ( FAILED(hr) ) - { - log_error("failed getting IMediaEventEx interface (%d)\n", hr); - goto constructionFailure; - } - - hr = pFilterGraph_->QueryInterface(IID_IMediaControl, - (void **)&pMediaControlIF_); - if ( FAILED(hr) ) - { - log_error("failed getting Media Control interface (%d)\n", hr); - goto constructionFailure; - } - // register filter graph - to monitor for errors during capture dshowMgr_->registerSrcGraph(src->src_info.identifier, this, pMediaEventIF_); @@ -187,12 +131,8 @@ constructionFailure: - if ( pMediaControlIF_ ) - pMediaControlIF_->Release(); + destroyCapGraphFoo(); - if ( pFilterGraph_ ) - pFilterGraph_->Release(); - if ( pSource_ ) pSource_->Release(); @@ -235,32 +175,147 @@ CloseHandle(eventTerminate_); } +int +DirectShowSource::createCapGraphFoo() +{ + HRESULT hr = CoCreateInstance(CLSID_CaptureGraphBuilder2, + NULL, + CLSCTX_INPROC_SERVER, + IID_ICaptureGraphBuilder2, + (void **)&pCapGraphBuilder_); + if ( FAILED(hr) ) + { + log_error("failed creating capture graph builder (%d)\n", hr); + return -1; + } + + hr = pCapGraphBuilder_->FindInterface(&PIN_CATEGORY_CAPTURE, + &MEDIATYPE_Video, + pSource_, + IID_IAMStreamConfig, + (void **)&pStreamConfig_); + if( FAILED(hr) ) + { + log_error("failed getting stream config (%d)\n", hr); + return -1; + } + + hr = CoCreateInstance(CLSID_FilterGraph, + 0, + CLSCTX_INPROC_SERVER, + IID_IGraphBuilder, + (void **)&pFilterGraph_); + if ( FAILED(hr) ) + { + log_error("failed creating the filter graph (%d)\n", hr); + return -1; + } + + hr = pCapGraphBuilder_->SetFiltergraph(pFilterGraph_); + if ( FAILED(hr) ) + { + log_error("failed setting the filter graph (%d)\n", hr); + return -1; + } + + hr = pFilterGraph_->QueryInterface(IID_IMediaEventEx, + (void **)&pMediaEventIF_); + if ( FAILED(hr) ) + { + log_error("failed getting IMediaEventEx interface (%d)\n", hr); + return -1; + } + + hr = pFilterGraph_->QueryInterface(IID_IMediaControl, + (void **)&pMediaControlIF_); + if ( FAILED(hr) ) + { + log_error("failed getting Media Control interface (%d)\n", hr); + return -1; + } + + hr = CoCreateInstance(CLSID_NullRenderer, + NULL, + CLSCTX_INPROC_SERVER, + IID_IBaseFilter, + (void **)&pNullRenderer_); + if ( FAILED(hr) ) + { + log_error("failed creating a NULL renderer (%d)\n", hr); + return -1; + } + + hr = CoCreateInstance(CLSID_SampleGrabber, + NULL, + CLSCTX_INPROC_SERVER, + IID_IBaseFilter, + (void **)&pSampleGrabber_); + if ( FAILED(hr) ) + { + log_error("failed creating Sample Grabber (%d)\n", hr); + return -1; + } + + hr = pSampleGrabber_->QueryInterface(IID_ISampleGrabber, + (void**)&pSampleGrabberIF_); + if ( FAILED(hr) ) + { + log_error("failed getting ISampleGrabber interface (%d)\n", hr); + return -1; + } + + // Capture more than once + hr = pSampleGrabberIF_->SetOneShot(FALSE); + if ( FAILED(hr) ) + { + log_error("failed SetOneShot (%d)\n", hr); + return -1; + } + + hr = pSampleGrabberIF_->SetBufferSamples(FALSE); + if ( FAILED(hr) ) + { + log_error("failed SetBufferSamples (%d)\n", hr); + return -1; + } + + // set which callback type and function to use + hr = pSampleGrabberIF_->SetCallback( this, 1 ); + if ( FAILED(hr) ) + { + log_error("failed to set callback (%d)\n", hr); + return -1; + } + + return 0; +} + void -DirectShowSource::terminate() +DirectShowSource::destroyCapGraphFoo() { - doStop(); + if ( pNullRenderer_ ) + pNullRenderer_->Release(); - cleanupCaptureGraphFoo(); + if ( pSampleGrabberIF_ ) + pSampleGrabberIF_->Release(); - if ( nativeMediaType_ ) - freeMediaType(*nativeMediaType_); + if ( pSampleGrabber_ ) + pSampleGrabber_->Release(); - // These below were initialized in constructor if ( pMediaControlIF_ ) pMediaControlIF_->Release(); - pMediaControlIF_ = 0; - pMediaEventIF_->Release(); + if ( pMediaEventIF_ ) + pMediaEventIF_->Release(); - pFilterGraph_->Release(); + if ( pFilterGraph_ ) + pFilterGraph_->Release(); - pSource_->Release(); + if ( pStreamConfig_ ) + pStreamConfig_->Release(); - pStreamConfig_->Release(); - - pCapGraphBuilder_->Release(); - - dshowMgr_->sourceReleased( getID() ); + if ( pCapGraphBuilder_ ) + pCapGraphBuilder_->Release(); } int @@ -412,111 +467,61 @@ } void -DirectShowSource::cleanupCaptureGraphFoo() +DirectShowSource::resetCapGraphFoo() { - if ( pNullRenderer_ ) - pNullRenderer_->Release(); - pNullRenderer_ = 0; + if ( captureIsSetup_ ) + { + // some or all of this appears to be necessary to allow + // subsequent captures with a different media type + HRESULT hr = pFilterGraph_->RemoveFilter(pSource_); + if ( FAILED(hr) ) + log_error("failed to remove source (%d)\n", hr); - if ( pSampleGrabberIF_ ) - pSampleGrabberIF_->Release(); - pSampleGrabberIF_ = 0; + hr = pFilterGraph_->RemoveFilter(pSampleGrabber_); + if ( FAILED(hr) ) + log_error("failed to remove Sample Grabber (%d)\n", + hr); - if ( pSampleGrabber_ ) - pSampleGrabber_->Release(); - pSampleGrabber_ = 0; + hr = pFilterGraph_->RemoveFilter(pNullRenderer_); + if ( FAILED(hr) ) + log_error("failed to remove null renderer (%d)\n", hr); - captureIsSetup_ = false; + captureIsSetup_ = false; + } } int -DirectShowSource::setupCaptureGraphFoo() +DirectShowSource::setupCapGraphFoo() { - if ( !captureIsSetup_ ) + if ( !captureIsSetup_ ) { - HRESULT hr = CoCreateInstance(CLSID_SampleGrabber, - NULL, - CLSCTX_INPROC_SERVER, - IID_IBaseFilter, - (void **)&pSampleGrabber_); - if ( FAILED(hr) ) - { - log_error("failed creating Sample Grabber (%d)\n", hr); - return -1; - } - - hr = pSampleGrabber_->QueryInterface(IID_ISampleGrabber, - (void**)&pSampleGrabberIF_); - if ( FAILED(hr) ) - { - log_error("failed getting ISampleGrabber interface (%d)\n", hr); - goto bail_1; - } - - // Capture more than once - hr = pSampleGrabberIF_->SetOneShot(FALSE); - if ( FAILED(hr) ) - { - log_error("failed SetOneShot (%d)\n", hr); - goto bail_2; - } - - hr = pSampleGrabberIF_->SetBufferSamples(FALSE); - if ( FAILED(hr) ) - { - log_error("failed SetBufferSamples (%d)\n", hr); - goto bail_2; - } - - // set which callback type and function to use - hr = pSampleGrabberIF_->SetCallback( this, 1 ); - if ( FAILED(hr) ) - { - log_error("failed to set callback (%d)\n", hr); - goto bail_2; - } - // Set sample grabber's media type to match that of the source - hr = pSampleGrabberIF_->SetMediaType(nativeMediaType_); + HRESULT hr = pSampleGrabberIF_->SetMediaType(nativeMediaType_); if ( FAILED(hr) ) { log_error("failed to set grabber media type (%d)\n", hr); - goto bail_2; + return -1; } - hr = CoCreateInstance(CLSID_NullRenderer, - NULL, - CLSCTX_INPROC_SERVER, - IID_IBaseFilter, - (void **)&pNullRenderer_); - - if ( FAILED(hr) ) - { - log_error("failed creating a NULL renderer (%d)\n", hr); - goto bail_2; - } - - //FIXME: use actual device name hr = pFilterGraph_->AddFilter(pSource_, L"Source Device"); if ( FAILED(hr) ) { log_error("failed to add source (%d)\n", hr); - goto bail_3; + return -1; } hr = pFilterGraph_->AddFilter(pSampleGrabber_, L"Sample Grabber"); if ( FAILED(hr) ) { - log_error("failed to add Sample Grabber to filter graph (%d)\n", - hr); - goto bail_3; + log_error("failed to add Sample Grabber (%d)\n", hr); + return -1; } hr = pFilterGraph_->AddFilter(pNullRenderer_, L"NullRenderer"); if ( FAILED(hr) ) { log_error("failed to add null renderer (%d)\n", hr); - goto bail_3; + return -1; } hr = pCapGraphBuilder_->RenderStream(&PIN_CATEGORY_CAPTURE, @@ -528,25 +533,28 @@ { log_error("failed to connect source, grabber " "and null renderer (%d)\n", hr); - goto bail_3; + return -1; } captureIsSetup_ = true; } return 0; +} -bail_3: - pNullRenderer_->Release(); - pNullRenderer_ = 0; -bail_2: - pSampleGrabberIF_->Release(); - pSampleGrabberIF_ = 0; -bail_1: - pSampleGrabber_->Release(); - pSampleGrabber_ = 0; +void +DirectShowSource::terminate() +{ + doStop(); - return -1; + if ( nativeMediaType_ ) + freeMediaType(*nativeMediaType_); + + destroyCapGraphFoo(); + + pSource_->Release(); + + dshowMgr_->sourceReleased( getID() ); } int @@ -566,7 +574,7 @@ void DirectShowSource::doStart() { - if ( !setupCaptureGraphFoo() ) + if ( !setupCapGraphFoo() ) { HRESULT hr = pMediaControlIF_->Run(); @@ -647,7 +655,7 @@ vih->bmiHeader.biWidth = fmtNative.width; vih->bmiHeader.biHeight = fmtNative.height; - cleanupCaptureGraphFoo(); + resetCapGraphFoo(); // set the stream's media type HRESULT hr = pStreamConfig_->SetFormat(nativeMediaType_); Modified: trunk/src/directshow/DirectShowSource.h =================================================================== --- trunk/src/directshow/DirectShowSource.h 2007-09-17 18:57:01 UTC (rev 22) +++ trunk/src/directshow/DirectShowSource.h 2007-09-18 17:14:56 UTC (rev 23) @@ -59,8 +59,10 @@ void doStop(); int createEvents(); - int setupCaptureGraphFoo(); - void cleanupCaptureGraphFoo(); + int createCapGraphFoo(); + void destroyCapGraphFoo(); + int setupCapGraphFoo(); + void resetCapGraphFoo(); bool checkFormat(const vidcap_fmt_info * fmtNominal, vidcap_fmt_info * fmtNative, int formatNum, 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-17 18:57:10
|
Revision: 22 http://libvidcap.svn.sourceforge.net/libvidcap/?rev=22&view=rev Author: bcholew Date: 2007-09-17 11:57:01 -0700 (Mon, 17 Sep 2007) Log Message: ----------- Create a thread for each DirectShowSource so that capture start/stop and source termination does not block the main thread. Modified Paths: -------------- trunk/src/directshow/DirectShowSource.cpp trunk/src/directshow/DirectShowSource.h Modified: trunk/src/directshow/DirectShowSource.cpp =================================================================== --- trunk/src/directshow/DirectShowSource.cpp 2007-09-13 19:53:30 UTC (rev 21) +++ trunk/src/directshow/DirectShowSource.cpp 2007-09-17 18:57:01 UTC (rev 22) @@ -51,7 +51,13 @@ pNullRenderer_(0), pMediaControlIF_(0), nativeMediaType_(0), - captureIsSetup_(false) + captureIsSetup_(false), + eventInitDone_(0), + eventStart_(0), + eventStop_(0), + eventTerminate_(0), + sourceThread_(0), + sourceThreadID_(0) { if ( !dshowMgr_ ) { @@ -153,8 +159,32 @@ // register filter graph - to monitor for errors during capture dshowMgr_->registerSrcGraph(src->src_info.identifier, this, pMediaEventIF_); - return; + if ( createEvents() ) + { + log_error("failed creating events for source thread"); + goto constructionFailure; + } + // 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: if ( pMediaControlIF_ ) @@ -176,8 +206,40 @@ DirectShowSource::~DirectShowSource() { - stop(); + 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("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_); +} + +void +DirectShowSource::terminate() +{ + doStop(); + cleanupCaptureGraphFoo(); if ( nativeMediaType_ ) @@ -201,6 +263,154 @@ dshowMgr_->sourceReleased( getID() ); } +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; + } + + return 0; +} + +DWORD WINAPI +DirectShowSource::waitForCmd(LPVOID lpParam) +{ + // extract instance + DirectShowSource * pSrc = (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 { startEventIndex = 0, stopEventIndex, + terminateEventIndex }; + + size_t numHandles = terminateEventIndex + 1; + HANDLE * waitHandles = new HANDLE [numHandles]; + + // ...plus something to break-out when a handle must be + // added or removed, or when thread must die + 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 == startEventIndex ) + { + pSrc->doStart(); + + if ( !ResetEvent(pSrc->eventStart_) ) + { + log_error("failed to reset source start event flag." + "Terminating.\n"); + // terminate + break; + } + } + else if ( index == stopEventIndex ) + { + pSrc->doStop(); + + if ( !ResetEvent(pSrc->eventStop_) ) + { + log_error("failed to reset source stop event flag." + "Terminating.\n"); + // terminate + break; + } + } + else if ( index == terminateEventIndex ) + { + pSrc->terminate(); + break; + } + } + + delete [] waitHandles; + + return 0; +} + void DirectShowSource::cleanupCaptureGraphFoo() { @@ -342,37 +552,61 @@ int DirectShowSource::start() { - if ( setupCaptureGraphFoo() ) + // signal to source thread to start capturing + if ( !SetEvent(eventStart_) ) + { + log_error("failed to signal source to start (%d)\n", + GetLastError()); return -1; + } - HRESULT hr = pMediaControlIF_->Run(); + return 0; +} - if ( FAILED(hr) ) +void +DirectShowSource::doStart() +{ + if ( !setupCaptureGraphFoo() ) { - log_error("failed to run filter graph for source '%s' (%ul 0x%x)\n", - sourceContext_->src_info.description, hr, hr); + HRESULT hr = pMediaControlIF_->Run(); - return -1; + if ( SUCCEEDED(hr) ) + return; + else + log_error("failed to run filter graph for source '%s' (%ul 0x%x)\n", + sourceContext_->src_info.description, hr, hr); } - return 0; + // call capture callback - with error status + // (vidcap will reset capture_callback) + sapi_src_capture_notify(sourceContext_, 0, 0, -1); } int DirectShowSource::stop() { + // signal to source thread to stop capturing + if ( !SetEvent(eventStop_) ) + { + log_error("failed to signal source to stop (%d)\n", + GetLastError()); + return -1; + } + + return 0; +} + +void +DirectShowSource::doStop() +{ if ( captureIsSetup_ ) { HRESULT hr = pMediaControlIF_->Stop(); if ( FAILED(hr) ) { log_error("failed to STOP the filter graph (0x%0x)\n", hr); - - return -1; } } - - return 0; } int Modified: trunk/src/directshow/DirectShowSource.h =================================================================== --- trunk/src/directshow/DirectShowSource.h 2007-09-13 19:53:30 UTC (rev 21) +++ trunk/src/directshow/DirectShowSource.h 2007-09-17 18:57:01 UTC (rev 22) @@ -53,6 +53,12 @@ } private: + static DWORD WINAPI waitForCmd(LPVOID); + void terminate(); + void doStart(); + void doStop(); + int createEvents(); + int setupCaptureGraphFoo(); void cleanupCaptureGraphFoo(); bool checkFormat(const vidcap_fmt_info * fmtNominal, @@ -97,6 +103,13 @@ IMediaControl * pMediaControlIF_; AM_MEDIA_TYPE *nativeMediaType_; bool captureIsSetup_; + + HANDLE eventInitDone_; + HANDLE eventStart_; + HANDLE eventStop_; + HANDLE eventTerminate_; + void * sourceThread_; + DWORD sourceThreadID_; }; #endif 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:54:29
|
Revision: 21 http://libvidcap.svn.sourceforge.net/libvidcap/?rev=21&view=rev Author: bcholew Date: 2007-09-13 12:53:30 -0700 (Thu, 13 Sep 2007) Log Message: ----------- Employ static mutex to prevent source destruction while it's capture callbacks are being cancelled by monitor thread (because of device removal). Consolidate acquiredSourceIDs_ into list of srcGraphContext structures. Consolidate unregisterSrcGraph() functionality into sourceRelease(). Move initialization of pMediaControlIF_ to source constructor (and Release to destructor). Use flag captureIsSetup_ to denote when capture graph foo has been setup for a source and given format (instead of pMediaControlIF_). Modified Paths: -------------- trunk/src/directshow/DShowSrcManager.cpp trunk/src/directshow/DShowSrcManager.h trunk/src/directshow/DirectShowSource.cpp trunk/src/directshow/DirectShowSource.h Modified: trunk/src/directshow/DShowSrcManager.cpp =================================================================== --- trunk/src/directshow/DShowSrcManager.cpp 2007-09-13 19:25:43 UTC (rev 20) +++ trunk/src/directshow/DShowSrcManager.cpp 2007-09-13 19:53:30 UTC (rev 21) @@ -38,10 +38,14 @@ #include "DirectShowSource.h" DShowSrcManager * DShowSrcManager::instance_ = 0; +CRITICAL_SECTION DShowSrcManager::sourceDestructionMutex_; DShowSrcManager::DShowSrcManager() : numRefs_(0) { + // one mutex for all graphMonitors + InitializeCriticalSection(&sourceDestructionMutex_); + graphMon_ = new GraphMonitor( (cancelCallbackFunc)&DShowSrcManager::cancelSrcCaptureCallback, this); @@ -58,11 +62,11 @@ { delete graphMon_; - acquiredSourceIDs_.erase( acquiredSourceIDs_.begin(), - acquiredSourceIDs_.end() ); srcGraphList_.erase( srcGraphList_.begin(), srcGraphList_.end() ); CoUninitialize(); + + DeleteCriticalSection(&sourceDestructionMutex_); } DShowSrcManager * @@ -94,49 +98,42 @@ } void -DShowSrcManager::registerSrcGraph(void *src, IMediaEventEx *pME) +DShowSrcManager::registerSrcGraph(const char *id, void *src, IMediaEventEx *pME) { - // create a context with all relevant info - srcGraphContext *pSrcGraphContext = new srcGraphContext(); - pSrcGraphContext->pME = pME; - pSrcGraphContext->pSrc = src; - - // add source graph context to list - srcGraphList_.push_back(pSrcGraphContext); - - // request that GraphMonitor monitor the graph for errors - graphMon_->addGraph(pME); -} - -void -DShowSrcManager::unregisterSrcGraph(IMediaEventEx *pME) -{ - // find appropriate source in list + // find appropriate source id in list for ( unsigned int i = 0; i < srcGraphList_.size(); i++ ) { - // found matching MediaEvent interface? - if ( srcGraphList_[i]->pME == pME ) + // found matching id? + if ( srcGraphList_[i]->sourceId == id ) { - // remove entry from srcGraphList_ - srcGraphContext *pSrcGraphContext = srcGraphList_[i]; - - srcGraphList_.erase( srcGraphList_.begin() + i ); - - delete pSrcGraphContext; - - // request that GraphMonitor stop monitoring the graph for errors - graphMon_->removeGraph(pME); - return; + // fill-in relevant info + srcGraphList_[i]->pSrc = src; + srcGraphList_[i]->pME = pME; + + // request that GraphMonitor monitor the graph for errors + graphMon_->addGraph(pME); } } - log_warn("failed to find source to unregister for monitoring\n"); } bool DShowSrcManager::cancelSrcCaptureCallback(IMediaEventEx *pME, void *ctx) { + bool ret = false; DShowSrcManager *self = static_cast<DShowSrcManager *>(ctx); + // NOTE: A source removal can be detected by both DevMonitor thread, + // and GraphMonitor thread. This can lead to cancellation of + // capture callbacks at the same time that the application + // is attempting to destroy the source. + // + // GraphMon -> cancelSrcCaptureCallback (this code) cancels callbacks + // DevMonitor -> app -> source destructor calls sourceReleased() + // + // Grab mutex to prevent concurrent access from this function and + // sourceReleased() + EnterCriticalSection(&sourceDestructionMutex_); + // find appropriate source in list for ( unsigned int i = 0; i < self->srcGraphList_.size(); i++ ) { @@ -144,17 +141,18 @@ if ( self->srcGraphList_[i]->pME == pME ) { // Found source to cancel callbacks for - // Call canceller DirectShowSource * pSrc = static_cast<DirectShowSource *>(self->srcGraphList_[i]->pSrc); // cancel the source's callback pSrc->cancelCallbacks(); - return true; + ret = true; + break; } } + LeaveCriticalSection(&sourceDestructionMutex_); - return false; + return ret; } int @@ -254,10 +252,10 @@ bool DShowSrcManager::okayToBuildSource(const char *id) { - // Enforce exclusive access to a source - for ( unsigned int i = 0; i < acquiredSourceIDs_.size(); i++ ) + // find appropriate source in list + for ( unsigned int i = 0; i < srcGraphList_.size(); i++ ) { - if ( !strcmp(acquiredSourceIDs_[i], id) ) + if ( !strcmp(srcGraphList_[i]->sourceId, id) ) { // a source with this id already exists - and was acquired log_warn("source already acquired: '%s'\n", id); @@ -265,26 +263,49 @@ } } + srcGraphContext *pSrcGraphContext = new srcGraphContext(); + pSrcGraphContext->sourceId = id; + + // these will be filled in later by registerSrcGraph() + pSrcGraphContext->pME = 0; + pSrcGraphContext->pSrc = 0; + // add source to collection - acquiredSourceIDs_.push_back(id); + srcGraphList_.push_back(pSrcGraphContext); return true; } void DShowSrcManager::sourceReleased(const char *id) { - for ( unsigned int i = 0; i < acquiredSourceIDs_.size(); i++ ) + // NOTE: see note in function cancelSrcCaptureCallback() + EnterCriticalSection(&sourceDestructionMutex_); + + // find appropriate source id in list + for ( unsigned int i = 0; i < srcGraphList_.size(); i++ ) { - if ( !strcmp(acquiredSourceIDs_[i], id) ) + // found matching source id? + if ( srcGraphList_[i]->sourceId == id ) { // found source with matching id - acquiredSourceIDs_.erase( acquiredSourceIDs_.begin() + i ); + // remove entry from srcGraphList_ + srcGraphContext *pSrcGraphContext = srcGraphList_[i]; + srcGraphList_.erase( srcGraphList_.begin() + i ); + + // request that GraphMonitor stop monitoring the graph for errors + graphMon_->removeGraph(pSrcGraphContext->pME); + + delete pSrcGraphContext; + + LeaveCriticalSection(&sourceDestructionMutex_); return; } } + LeaveCriticalSection(&sourceDestructionMutex_); + log_warn("couldn't find source '%s' to release\n", id); } Modified: trunk/src/directshow/DShowSrcManager.h =================================================================== --- trunk/src/directshow/DShowSrcManager.h 2007-09-13 19:25:43 UTC (rev 20) +++ trunk/src/directshow/DShowSrcManager.h 2007-09-13 19:53:30 UTC (rev 21) @@ -44,8 +44,7 @@ int registerNotifyCallback(void *); // to monitor for graph errors during capture - void registerSrcGraph(void *, IMediaEventEx *); - void unregisterSrcGraph(IMediaEventEx *pME); + void registerSrcGraph(const char *, void *, IMediaEventEx *); // graphMon_ callback to request capture abort typedef bool (*cancelCallbackFunc)(IMediaEventEx *, void *); @@ -61,7 +60,6 @@ private: static DShowSrcManager *instance_; int numRefs_; - std::vector<const char *> acquiredSourceIDs_; DevMonitor devMon_; GraphMonitor *graphMon_; @@ -70,11 +68,17 @@ { IMediaEventEx * pME; void * pSrc; + const char * sourceId; }; - // list of sources and their filter graphs + // list of acquired sources, their filter graphs, and IDs std::vector<srcGraphContext *> srcGraphList_; + // prevent DevMonitor -> app -> src destructor from destroying + // source while GraphMon -> cancelSrcCaptureCallback + // is in the midst of cancelling callbacks + static CRITICAL_SECTION sourceDestructionMutex_; + private: IPin * getOutPin( IBaseFilter *, int) const; HRESULT getPin( IBaseFilter *, PIN_DIRECTION, int, IPin **) const; Modified: trunk/src/directshow/DirectShowSource.cpp =================================================================== --- trunk/src/directshow/DirectShowSource.cpp 2007-09-13 19:25:43 UTC (rev 20) +++ trunk/src/directshow/DirectShowSource.cpp 2007-09-13 19:53:30 UTC (rev 21) @@ -50,7 +50,8 @@ pSampleGrabberIF_(0), pNullRenderer_(0), pMediaControlIF_(0), - nativeMediaType_(0) + nativeMediaType_(0), + captureIsSetup_(false) { if ( !dshowMgr_ ) { @@ -141,14 +142,24 @@ goto constructionFailure; } + hr = pFilterGraph_->QueryInterface(IID_IMediaControl, + (void **)&pMediaControlIF_); + if ( FAILED(hr) ) + { + log_error("failed getting Media Control interface (%d)\n", hr); + goto constructionFailure; + } + // register filter graph - to monitor for errors during capture - // FIXME: Is this too early? Should we only do it during captures? - dshowMgr_->registerSrcGraph(this, pMediaEventIF_); + dshowMgr_->registerSrcGraph(src->src_info.identifier, this, pMediaEventIF_); return; constructionFailure: + if ( pMediaControlIF_ ) + pMediaControlIF_->Release(); + if ( pFilterGraph_ ) pFilterGraph_->Release(); @@ -169,12 +180,14 @@ cleanupCaptureGraphFoo(); - dshowMgr_->unregisterSrcGraph(pMediaEventIF_); - if ( nativeMediaType_ ) freeMediaType(*nativeMediaType_); // These below were initialized in constructor + if ( pMediaControlIF_ ) + pMediaControlIF_->Release(); + pMediaControlIF_ = 0; + pMediaEventIF_->Release(); pFilterGraph_->Release(); @@ -203,25 +216,15 @@ pSampleGrabber_->Release(); pSampleGrabber_ = 0; - if ( pMediaControlIF_ ) - pMediaControlIF_->Release(); - pMediaControlIF_ = 0; + captureIsSetup_ = false; } int DirectShowSource::setupCaptureGraphFoo() { - if ( !pMediaControlIF_ ) + if ( !captureIsSetup_ ) { - HRESULT hr = pFilterGraph_->QueryInterface(IID_IMediaControl, - (void **)&pMediaControlIF_); - if ( FAILED(hr) ) - { - log_error("failed getting Media Control interface (%d)\n", hr); - return -1; - } - - hr = CoCreateInstance(CLSID_SampleGrabber, + HRESULT hr = CoCreateInstance(CLSID_SampleGrabber, NULL, CLSCTX_INPROC_SERVER, IID_IBaseFilter, @@ -229,7 +232,7 @@ if ( FAILED(hr) ) { log_error("failed creating Sample Grabber (%d)\n", hr); - goto bail_1; + return -1; } hr = pSampleGrabber_->QueryInterface(IID_ISampleGrabber, @@ -237,7 +240,7 @@ if ( FAILED(hr) ) { log_error("failed getting ISampleGrabber interface (%d)\n", hr); - goto bail_2; + goto bail_1; } // Capture more than once @@ -245,14 +248,14 @@ if ( FAILED(hr) ) { log_error("failed SetOneShot (%d)\n", hr); - goto bail_3; + goto bail_2; } hr = pSampleGrabberIF_->SetBufferSamples(FALSE); if ( FAILED(hr) ) { log_error("failed SetBufferSamples (%d)\n", hr); - goto bail_3; + goto bail_2; } // set which callback type and function to use @@ -260,7 +263,7 @@ if ( FAILED(hr) ) { log_error("failed to set callback (%d)\n", hr); - goto bail_3; + goto bail_2; } // Set sample grabber's media type to match that of the source @@ -268,7 +271,7 @@ if ( FAILED(hr) ) { log_error("failed to set grabber media type (%d)\n", hr); - goto bail_3; + goto bail_2; } hr = CoCreateInstance(CLSID_NullRenderer, @@ -280,7 +283,7 @@ if ( FAILED(hr) ) { log_error("failed creating a NULL renderer (%d)\n", hr); - goto bail_3; + goto bail_2; } //FIXME: use actual device name @@ -288,7 +291,7 @@ if ( FAILED(hr) ) { log_error("failed to add source (%d)\n", hr); - goto bail_4; + goto bail_3; } hr = pFilterGraph_->AddFilter(pSampleGrabber_, L"Sample Grabber"); @@ -296,14 +299,14 @@ { log_error("failed to add Sample Grabber to filter graph (%d)\n", hr); - goto bail_4; + goto bail_3; } hr = pFilterGraph_->AddFilter(pNullRenderer_, L"NullRenderer"); if ( FAILED(hr) ) { log_error("failed to add null renderer (%d)\n", hr); - goto bail_4; + goto bail_3; } hr = pCapGraphBuilder_->RenderStream(&PIN_CATEGORY_CAPTURE, @@ -315,24 +318,23 @@ { log_error("failed to connect source, grabber " "and null renderer (%d)\n", hr); - goto bail_4; + goto bail_3; } + + captureIsSetup_ = true; } return 0; -bail_4: +bail_3: pNullRenderer_->Release(); pNullRenderer_ = 0; -bail_3: +bail_2: pSampleGrabberIF_->Release(); pSampleGrabberIF_ = 0; -bail_2: +bail_1: pSampleGrabber_->Release(); pSampleGrabber_ = 0; -bail_1: - pMediaControlIF_->Release(); - pMediaControlIF_ = 0; return -1; } @@ -359,20 +361,18 @@ int DirectShowSource::stop() { - int ret = 0; - - if ( pMediaControlIF_ ) + if ( captureIsSetup_ ) { HRESULT hr = pMediaControlIF_->Stop(); if ( FAILED(hr) ) { log_error("failed to STOP the filter graph (0x%0x)\n", hr); - ret = -1; + return -1; } } - return ret; + return 0; } int @@ -718,11 +718,11 @@ void DirectShowSource::cancelCallbacks() { - // have capture callbacks already been cancelled? + // have buffer callbacks already been cancelled? if ( !sourceContext_->capture_callback ) return; - // stop callbacks BEFORE thinking of + // stop callbacks before thinking of // touching sourceContext_->capture_callback stop(); Modified: trunk/src/directshow/DirectShowSource.h =================================================================== --- trunk/src/directshow/DirectShowSource.h 2007-09-13 19:25:43 UTC (rev 20) +++ trunk/src/directshow/DirectShowSource.h 2007-09-13 19:53:30 UTC (rev 21) @@ -96,6 +96,7 @@ IBaseFilter * pNullRenderer_; IMediaControl * pMediaControlIF_; AM_MEDIA_TYPE *nativeMediaType_; + bool captureIsSetup_; }; #endif 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-13 18:33:15
|
Revision: 19 http://libvidcap.svn.sourceforge.net/libvidcap/?rev=19&view=rev Author: jpgrayson Date: 2007-09-13 11:32:29 -0700 (Thu, 13 Sep 2007) Log Message: ----------- Fix problem with starting and stopping capture by making sure we sync with all the frames we start capture for. Modified Paths: -------------- trunk/src/sapi_v4l.c Modified: trunk/src/sapi_v4l.c =================================================================== --- trunk/src/sapi_v4l.c 2007-09-13 13:05:21 UTC (rev 18) +++ trunk/src/sapi_v4l.c 2007-09-13 18:32:29 UTC (rev 19) @@ -43,7 +43,7 @@ enum { - DEVICE_PATH_MAX = 128, + device_path_max = 128, v4l_fps_mask = 0x003f0000, v4l_fps_shift = 16, }; @@ -58,7 +58,7 @@ struct sapi_v4l_src_context { int fd; - char device_path[DEVICE_PATH_MAX]; + char device_path[device_path_max]; int channel; struct video_capability caps; @@ -256,7 +256,7 @@ scan_sources(struct sapi_context * sapi_ctx, struct sapi_src_list * src_list) { static const char * device_prefix = "/dev/video"; - char device_path[DEVICE_PATH_MAX]; + char device_path[device_path_max]; int list_len = 0; int i; @@ -357,6 +357,22 @@ ++capture_frame_count; } + /* Sync with the last frame when capture has stopped (since we + * have overlapped capture kickoffs). + */ + { + const unsigned int capture_frame = + capture_frame_count % v4l_src_ctx->mbuf.frames; + + if ( ioctl( v4l_src_ctx->fd, VIDIOCSYNC, + &capture_frame ) == -1 ) + { + log_error("failed VIDIOCSYNC (2) %d\n", errno); + goto bail; + } + } + + if ( munmap((void *)fb_base, v4l_src_ctx->mbuf.size) == -1 ) { log_error("failed munmap() %d\n", errno); 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 13:05:23
|
Revision: 18 http://libvidcap.svn.sourceforge.net/libvidcap/?rev=18&view=rev Author: bcholew Date: 2007-09-13 06:05:21 -0700 (Thu, 13 Sep 2007) Log Message: ----------- When cancelling capture callbacks, stop() capture before calling final callback. This removes the need for a mutex to protect capture_callback from simultaneous access by cancelCallbacks() and an actual capture callback ( BufferCB() ). Modified Paths: -------------- trunk/src/directshow/DirectShowSource.cpp trunk/src/directshow/DirectShowSource.h Modified: trunk/src/directshow/DirectShowSource.cpp =================================================================== --- trunk/src/directshow/DirectShowSource.cpp 2007-09-12 18:05:45 UTC (rev 17) +++ trunk/src/directshow/DirectShowSource.cpp 2007-09-13 13:05:21 UTC (rev 18) @@ -50,8 +50,7 @@ pSampleGrabberIF_(0), pNullRenderer_(0), pMediaControlIF_(0), - nativeMediaType_(0), - stoppingCapture_(false) + nativeMediaType_(0) { if ( !dshowMgr_ ) { @@ -146,8 +145,6 @@ // FIXME: Is this too early? Should we only do it during captures? dshowMgr_->registerSrcGraph(this, pMediaEventIF_); - InitializeCriticalSection(&captureMutex_); - return; constructionFailure: @@ -189,8 +186,6 @@ pCapGraphBuilder_->Release(); dshowMgr_->sourceReleased( getID() ); - - DeleteCriticalSection(&captureMutex_); } void @@ -336,10 +331,8 @@ pSampleGrabber_->Release(); pSampleGrabber_ = 0; bail_1: - EnterCriticalSection(&captureMutex_); pMediaControlIF_->Release(); pMediaControlIF_ = 0; - LeaveCriticalSection(&captureMutex_); return -1; } @@ -367,10 +360,7 @@ DirectShowSource::stop() { int ret = 0; - stoppingCapture_ = true; - EnterCriticalSection(&captureMutex_); - if ( pMediaControlIF_ ) { HRESULT hr = pMediaControlIF_->Stop(); @@ -382,10 +372,6 @@ } } - LeaveCriticalSection(&captureMutex_); - - stoppingCapture_ = false; - return ret; } @@ -732,23 +718,18 @@ void DirectShowSource::cancelCallbacks() { - // serialize with normal capture callbacks - EnterCriticalSection(&captureMutex_); - - // only cancel callbacks once (unless re-registered) + // have capture callbacks already been cancelled? if ( !sourceContext_->capture_callback ) - { - LeaveCriticalSection(&captureMutex_); return; - } - // call capture callback - but let the + // stop callbacks BEFORE thinking of + // touching sourceContext_->capture_callback + stop(); + + // call capture callback - but let vidcap and the // app know that this is the last time + // (vidcap will reset capture_callback) sapi_src_capture_notify(sourceContext_, 0, 0, -1); - - LeaveCriticalSection(&captureMutex_); - - stop(); } STDMETHODIMP @@ -770,22 +751,12 @@ STDMETHODIMP DirectShowSource::BufferCB( double dblSampleTime, BYTE * pBuff, long buffSize ) { - // prevent deadlock while stopping - if ( stoppingCapture_ ) - return 0; - - EnterCriticalSection(&captureMutex_); - if ( !sourceContext_->capture_callback ) return 0; - int ret = sapi_src_capture_notify(sourceContext_, + return sapi_src_capture_notify(sourceContext_, reinterpret_cast<const char *>(pBuff), static_cast<int>(buffSize), 0); - - LeaveCriticalSection(&captureMutex_); - - return ret; } int Modified: trunk/src/directshow/DirectShowSource.h =================================================================== --- trunk/src/directshow/DirectShowSource.h 2007-09-12 18:05:45 UTC (rev 17) +++ trunk/src/directshow/DirectShowSource.h 2007-09-13 13:05:21 UTC (rev 18) @@ -96,8 +96,6 @@ IBaseFilter * pNullRenderer_; IMediaControl * pMediaControlIF_; AM_MEDIA_TYPE *nativeMediaType_; - CRITICAL_SECTION captureMutex_; - bool stoppingCapture_; }; #endif 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-12 18:05:47
|
Revision: 17 http://libvidcap.svn.sourceforge.net/libvidcap/?rev=17&view=rev Author: bcholew Date: 2007-09-12 11:05:45 -0700 (Wed, 12 Sep 2007) Log Message: ----------- Add functions to setup and cleanup capture graph foo. Cleanup capture graph foo at bind time and in destructor. Only setup capture graph foo at capture start time if it's not already been done. Modified Paths: -------------- trunk/src/directshow/DirectShowSource.cpp trunk/src/directshow/DirectShowSource.h Modified: trunk/src/directshow/DirectShowSource.cpp =================================================================== --- trunk/src/directshow/DirectShowSource.cpp 2007-09-12 13:57:59 UTC (rev 16) +++ trunk/src/directshow/DirectShowSource.cpp 2007-09-12 18:05:45 UTC (rev 17) @@ -170,6 +170,8 @@ { stop(); + cleanupCaptureGraphFoo(); + dshowMgr_->unregisterSrcGraph(pMediaEventIF_); if ( nativeMediaType_ ) @@ -191,130 +193,139 @@ DeleteCriticalSection(&captureMutex_); } -int -DirectShowSource::start() +void +DirectShowSource::cleanupCaptureGraphFoo() { - HRESULT hr = pFilterGraph_->QueryInterface(IID_IMediaControl, - (void **)&pMediaControlIF_); - if ( FAILED(hr) ) - { - log_error("failed getting Media Control interface (%d)\n", hr); - return -1; - } + if ( pNullRenderer_ ) + pNullRenderer_->Release(); + pNullRenderer_ = 0; - hr = CoCreateInstance(CLSID_SampleGrabber, - NULL, - CLSCTX_INPROC_SERVER, - IID_IBaseFilter, - (void **)&pSampleGrabber_); - if ( FAILED(hr) ) - { - log_error("failed creating Sample Grabber (%d)\n", hr); - goto bail_1; - } + if ( pSampleGrabberIF_ ) + pSampleGrabberIF_->Release(); + pSampleGrabberIF_ = 0; - hr = pSampleGrabber_->QueryInterface(IID_ISampleGrabber, - (void**)&pSampleGrabberIF_); - if ( FAILED(hr) ) - { - log_error("failed getting ISampleGrabber interface (%d)\n", hr); - goto bail_2; - } + if ( pSampleGrabber_ ) + pSampleGrabber_->Release(); + pSampleGrabber_ = 0; - // Capture more than once - hr = pSampleGrabberIF_->SetOneShot(FALSE); - if ( FAILED(hr) ) - { - log_error("failed SetOneShot (%d)\n", hr); - goto bail_3; - } + if ( pMediaControlIF_ ) + pMediaControlIF_->Release(); + pMediaControlIF_ = 0; +} - hr = pSampleGrabberIF_->SetBufferSamples(FALSE); - if ( FAILED(hr) ) +int +DirectShowSource::setupCaptureGraphFoo() +{ + if ( !pMediaControlIF_ ) { - log_error("failed SetBufferSamples (%d)\n", hr); - goto bail_3; - } + HRESULT hr = pFilterGraph_->QueryInterface(IID_IMediaControl, + (void **)&pMediaControlIF_); + if ( FAILED(hr) ) + { + log_error("failed getting Media Control interface (%d)\n", hr); + return -1; + } - // set which callback type and function to use - hr = pSampleGrabberIF_->SetCallback( this, 1 ); - if ( FAILED(hr) ) - { - log_error("failed to set callback (%d)\n", hr); - goto bail_3; - } + hr = CoCreateInstance(CLSID_SampleGrabber, + NULL, + CLSCTX_INPROC_SERVER, + IID_IBaseFilter, + (void **)&pSampleGrabber_); + if ( FAILED(hr) ) + { + log_error("failed creating Sample Grabber (%d)\n", hr); + goto bail_1; + } - // Set sample grabber's media type to match that of the source - hr = pSampleGrabberIF_->SetMediaType(nativeMediaType_); - if ( FAILED(hr) ) - { - log_error("failed to set grabber media type (%d)\n", hr); - goto bail_3; - } + hr = pSampleGrabber_->QueryInterface(IID_ISampleGrabber, + (void**)&pSampleGrabberIF_); + if ( FAILED(hr) ) + { + log_error("failed getting ISampleGrabber interface (%d)\n", hr); + goto bail_2; + } - hr = CoCreateInstance(CLSID_NullRenderer, - NULL, - CLSCTX_INPROC_SERVER, - IID_IBaseFilter, - (void **)&pNullRenderer_); + // Capture more than once + hr = pSampleGrabberIF_->SetOneShot(FALSE); + if ( FAILED(hr) ) + { + log_error("failed SetOneShot (%d)\n", hr); + goto bail_3; + } - if ( FAILED(hr) ) - { - log_error("failed creating a NULL renderer (%d)\n", hr); - goto bail_3; - } + hr = pSampleGrabberIF_->SetBufferSamples(FALSE); + if ( FAILED(hr) ) + { + log_error("failed SetBufferSamples (%d)\n", hr); + goto bail_3; + } - //FIXME: use actual device name - hr = pFilterGraph_->AddFilter(pSource_, L"Source Device"); - if ( FAILED(hr) ) - { - log_error("failed to add source (%d)\n", hr); - goto bail_4; - } + // set which callback type and function to use + hr = pSampleGrabberIF_->SetCallback( this, 1 ); + if ( FAILED(hr) ) + { + log_error("failed to set callback (%d)\n", hr); + goto bail_3; + } - hr = pFilterGraph_->AddFilter(pSampleGrabber_, L"Sample Grabber"); - if ( FAILED(hr) ) - { - log_error("failed to add Sample Grabber to filter graph (%d)\n", - hr); - goto bail_4; - } + // Set sample grabber's media type to match that of the source + hr = pSampleGrabberIF_->SetMediaType(nativeMediaType_); + if ( FAILED(hr) ) + { + log_error("failed to set grabber media type (%d)\n", hr); + goto bail_3; + } - hr = pFilterGraph_->AddFilter(pNullRenderer_, L"NullRenderer"); - if ( FAILED(hr) ) - { - log_error("failed to add null renderer (%d)\n", hr); - goto bail_4; - } + hr = CoCreateInstance(CLSID_NullRenderer, + NULL, + CLSCTX_INPROC_SERVER, + IID_IBaseFilter, + (void **)&pNullRenderer_); - hr = pCapGraphBuilder_->RenderStream(&PIN_CATEGORY_CAPTURE, - &MEDIATYPE_Video, - pSource_, - pSampleGrabber_, - pNullRenderer_); - if ( FAILED(hr) ) - { - log_error("failed to connect source, grabber " - "and null renderer (%d)\n", hr); - goto bail_4; - } + if ( FAILED(hr) ) + { + log_error("failed creating a NULL renderer (%d)\n", hr); + goto bail_3; + } - hr = pMediaControlIF_->Run(); + //FIXME: use actual device name + hr = pFilterGraph_->AddFilter(pSource_, L"Source Device"); + if ( FAILED(hr) ) + { + log_error("failed to add source (%d)\n", hr); + goto bail_4; + } - if ( SUCCEEDED(hr) ) - { - return 0; - } + hr = pFilterGraph_->AddFilter(pSampleGrabber_, L"Sample Grabber"); + if ( FAILED(hr) ) + { + log_error("failed to add Sample Grabber to filter graph (%d)\n", + hr); + goto bail_4; + } - log_error("failed to run filter graph for source '%s' (%ul 0x%x)\n", - sourceContext_->src_info.description, hr, hr); + hr = pFilterGraph_->AddFilter(pNullRenderer_, L"NullRenderer"); + if ( FAILED(hr) ) + { + log_error("failed to add null renderer (%d)\n", hr); + goto bail_4; + } - hr = pMediaControlIF_->Stop(); - if ( FAILED(hr) ) - { - log_error("failed to STOP filter graph (%ul)\n", hr); + hr = pCapGraphBuilder_->RenderStream(&PIN_CATEGORY_CAPTURE, + &MEDIATYPE_Video, + pSource_, + pSampleGrabber_, + pNullRenderer_); + if ( FAILED(hr) ) + { + log_error("failed to connect source, grabber " + "and null renderer (%d)\n", hr); + goto bail_4; + } } + return 0; + bail_4: pNullRenderer_->Release(); pNullRenderer_ = 0; @@ -334,8 +345,28 @@ } int +DirectShowSource::start() +{ + if ( setupCaptureGraphFoo() ) + return -1; + + HRESULT hr = pMediaControlIF_->Run(); + + if ( FAILED(hr) ) + { + log_error("failed to run filter graph for source '%s' (%ul 0x%x)\n", + sourceContext_->src_info.description, hr, hr); + + return -1; + } + + return 0; +} + +int DirectShowSource::stop() { + int ret = 0; stoppingCapture_ = true; EnterCriticalSection(&captureMutex_); @@ -345,30 +376,17 @@ HRESULT hr = pMediaControlIF_->Stop(); if ( FAILED(hr) ) { - log_error("failed to STOP the filter graph (%ul)\n", hr); + log_error("failed to STOP the filter graph (0x%0x)\n", hr); + + ret = -1; } - - if ( pNullRenderer_ ) - pNullRenderer_->Release(); - pNullRenderer_ = 0; - - if ( pSampleGrabberIF_ ) - pSampleGrabberIF_->Release(); - pSampleGrabberIF_ = 0; - - if ( pSampleGrabber_ ) - pSampleGrabber_->Release(); - pSampleGrabber_ = 0; - - pMediaControlIF_->Release(); - pMediaControlIF_ = 0; } LeaveCriticalSection(&captureMutex_); stoppingCapture_ = false; - return 0; + return ret; } int @@ -409,6 +427,8 @@ vih->bmiHeader.biWidth = fmtNative.width; vih->bmiHeader.biHeight = fmtNative.height; + cleanupCaptureGraphFoo(); + // set the stream's media type HRESULT hr = pStreamConfig_->SetFormat(nativeMediaType_); if ( FAILED(hr) ) Modified: trunk/src/directshow/DirectShowSource.h =================================================================== --- trunk/src/directshow/DirectShowSource.h 2007-09-12 13:57:59 UTC (rev 16) +++ trunk/src/directshow/DirectShowSource.h 2007-09-12 18:05:45 UTC (rev 17) @@ -53,6 +53,8 @@ } private: + int setupCaptureGraphFoo(); + void cleanupCaptureGraphFoo(); bool checkFormat(const vidcap_fmt_info * fmtNominal, vidcap_fmt_info * fmtNative, int formatNum, 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-12 13:58:09
|
Revision: 16 http://libvidcap.svn.sourceforge.net/libvidcap/?rev=16&view=rev Author: bcholew Date: 2007-09-12 06:57:59 -0700 (Wed, 12 Sep 2007) Log Message: ----------- Rename sourceIDs_ to acquiredSourceIDs_. Constify scan(), getJustCapDevice(), sprintDeviceInfo(), getOutPin(), getPin(), and getDeviceInfo(). Privatize getOutPin(). Remove getInPin(). Move freeMediaType() to DirectShowSource. Tidy up. Modified Paths: -------------- trunk/src/directshow/DShowSrcManager.cpp trunk/src/directshow/DShowSrcManager.h trunk/src/directshow/DirectShowSource.cpp trunk/src/directshow/DirectShowSource.h Modified: trunk/src/directshow/DShowSrcManager.cpp =================================================================== --- trunk/src/directshow/DShowSrcManager.cpp 2007-09-11 18:43:51 UTC (rev 15) +++ trunk/src/directshow/DShowSrcManager.cpp 2007-09-12 13:57:59 UTC (rev 16) @@ -58,7 +58,8 @@ { delete graphMon_; - sourceIDs_.erase( sourceIDs_.begin(), sourceIDs_.end() ); + acquiredSourceIDs_.erase( acquiredSourceIDs_.begin(), + acquiredSourceIDs_.end() ); srcGraphList_.erase( srcGraphList_.begin(), srcGraphList_.end() ); CoUninitialize(); @@ -157,7 +158,7 @@ } int -DShowSrcManager::scan(struct sapi_src_list * srcList) +DShowSrcManager::scan(struct sapi_src_list * srcList) const { //FIXME: consider multiple sources per device @@ -254,9 +255,9 @@ DShowSrcManager::okayToBuildSource(const char *id) { // Enforce exclusive access to a source - for ( unsigned int i = 0; i < sourceIDs_.size(); i++ ) + for ( unsigned int i = 0; i < acquiredSourceIDs_.size(); i++ ) { - if ( !strcmp(sourceIDs_[i], id) ) + if ( !strcmp(acquiredSourceIDs_[i], id) ) { // a source with this id already exists - and was acquired log_warn("source already acquired: '%s'\n", id); @@ -265,20 +266,20 @@ } // add source to collection - sourceIDs_.push_back(id); + acquiredSourceIDs_.push_back(id); return true; } void DShowSrcManager::sourceReleased(const char *id) { - for ( unsigned int i = 0; i < sourceIDs_.size(); i++ ) + for ( unsigned int i = 0; i < acquiredSourceIDs_.size(); i++ ) { - if ( !strcmp(sourceIDs_[i], id) ) + if ( !strcmp(acquiredSourceIDs_[i], id) ) { // found source with matching id - sourceIDs_.erase( sourceIDs_.begin() + i ); + acquiredSourceIDs_.erase( acquiredSourceIDs_.begin() + i ); return; } @@ -287,30 +288,10 @@ log_warn("couldn't find source '%s' to release\n", id); } -IPin * -DShowSrcManager::getOutPin( IBaseFilter * pFilter, int nPin ) -{ - CComPtr<IPin> pComPin = 0; - - getPin(pFilter, PINDIR_OUTPUT, nPin, &pComPin); - - return pComPin; -} - -void -DShowSrcManager::freeMediaType(AM_MEDIA_TYPE& mt) -{ - if ( mt.cbFormat != 0 ) - CoTaskMemFree((PVOID)mt.pbFormat); - - if ( mt.pUnk != NULL ) - mt.pUnk->Release(); -} - bool DShowSrcManager::getJustCapDevice(const char *devLongName, IBindCtx **ppBindCtx, - IMoniker **ppMoniker) + IMoniker **ppMoniker) const { HRESULT hr; @@ -395,7 +376,7 @@ void DShowSrcManager::sprintDeviceInfo(IMoniker * pM, IBindCtx * pbc, - char* idBuff, char *descBuff, int buffsSize) + char* idBuff, char *descBuff, int buffsSize) const { USES_CONVERSION; @@ -454,16 +435,18 @@ } IPin * -DShowSrcManager::getInPin( IBaseFilter * pFilter, int nPin ) +DShowSrcManager::getOutPin( IBaseFilter * pFilter, int nPin ) const { CComPtr<IPin> pComPin = 0; - getPin(pFilter, PINDIR_INPUT, nPin, &pComPin); + + getPin(pFilter, PINDIR_OUTPUT, nPin, &pComPin); + return pComPin; } HRESULT DShowSrcManager::getPin( IBaseFilter * pFilter, PIN_DIRECTION dirrequired, - int iNum, IPin **ppPin) + int iNum, IPin **ppPin) const { *ppPin = NULL; @@ -505,7 +488,7 @@ // Allocates and returns the friendlyName and displayName for a device int DShowSrcManager::getDeviceInfo(IMoniker * pM, IBindCtx * pbc, - char** easyName, char **longName) + char** easyName, char **longName) const { USES_CONVERSION; Modified: trunk/src/directshow/DShowSrcManager.h =================================================================== --- trunk/src/directshow/DShowSrcManager.h 2007-09-11 18:43:51 UTC (rev 15) +++ trunk/src/directshow/DShowSrcManager.h 2007-09-12 13:57:59 UTC (rev 16) @@ -38,7 +38,7 @@ public: static DShowSrcManager * instance(); - int scan(struct sapi_src_list *); + int scan(struct sapi_src_list *) const; // for device event notifications (additions and removals) int registerNotifyCallback(void *); @@ -51,12 +51,9 @@ typedef bool (*cancelCallbackFunc)(IMediaEventEx *, void *); static bool cancelSrcCaptureCallback(IMediaEventEx *, void *); - IPin * getOutPin( IBaseFilter *, int); - IPin * getInPin( IBaseFilter *, int); - void freeMediaType(AM_MEDIA_TYPE& mt); bool getJustCapDevice(const char *devLongName, IBindCtx **ppBindCtx, - IMoniker **ppMoniker); + IMoniker **ppMoniker) const; bool okayToBuildSource(const char *); void sourceReleased(const char *id); void release(); @@ -64,7 +61,7 @@ private: static DShowSrcManager *instance_; int numRefs_; - std::vector<const char *> sourceIDs_; + std::vector<const char *> acquiredSourceIDs_; DevMonitor devMon_; GraphMonitor *graphMon_; @@ -79,10 +76,11 @@ std::vector<srcGraphContext *> srcGraphList_; private: - HRESULT getPin( IBaseFilter *, PIN_DIRECTION, int, IPin **); + IPin * getOutPin( IBaseFilter *, int) const; + HRESULT getPin( IBaseFilter *, PIN_DIRECTION, int, IPin **) const; int getDeviceInfo(IMoniker * pM, IBindCtx * pbc, - char** easyName, char **longName); - void sprintDeviceInfo(IMoniker *, IBindCtx *, char *, char *, int); + char** easyName, char **longName) const; + void sprintDeviceInfo(IMoniker *, IBindCtx *, char *, char *, int) const; }; #endif Modified: trunk/src/directshow/DirectShowSource.cpp =================================================================== --- trunk/src/directshow/DirectShowSource.cpp 2007-09-11 18:43:51 UTC (rev 15) +++ trunk/src/directshow/DirectShowSource.cpp 2007-09-12 13:57:59 UTC (rev 16) @@ -173,7 +173,7 @@ dshowMgr_->unregisterSrcGraph(pMediaEventIF_); if ( nativeMediaType_ ) - dshowMgr_->freeMediaType(*nativeMediaType_); + freeMediaType(*nativeMediaType_); // These below were initialized in constructor pMediaEventIF_->Release(); @@ -380,7 +380,7 @@ if ( !findBestFormat(fmtNominal, fmtNative, &mediaFormat) ) return 0; - dshowMgr_->freeMediaType(*mediaFormat); + freeMediaType(*mediaFormat); return 1; } @@ -392,7 +392,7 @@ // If we've already got one, free it if ( nativeMediaType_ ) { - dshowMgr_->freeMediaType(*nativeMediaType_); + freeMediaType(*nativeMediaType_); nativeMediaType_ = 0; } @@ -415,7 +415,7 @@ { log_error("failed setting stream format (%d)\n", hr); - dshowMgr_->freeMediaType(*nativeMediaType_); + freeMediaType(*nativeMediaType_); nativeMediaType_ = 0; return 1; @@ -549,7 +549,7 @@ { // NOT the chosen one? if ( !itCanWork || iFmt != bestFmtNum ) - dshowMgr_->freeMediaType(*candidateFmtProps[iFmt].mediaFormat); + freeMediaType(*candidateFmtProps[iFmt].mediaFormat); } } @@ -604,7 +604,7 @@ fmtNominal->width > scc.MaxOutputSize.cx || fmtNominal->height > scc.MaxOutputSize.cy ) { - dshowMgr_->freeMediaType(*pMediaType); + freeMediaType(*pMediaType); return false; } @@ -632,7 +632,7 @@ if ( !matchesWidth || !matchesHeight ) { - dshowMgr_->freeMediaType(*pMediaType); + freeMediaType(*pMediaType); return false; } @@ -648,7 +648,7 @@ // check framerate if ( fps > fpsMax ) { - dshowMgr_->freeMediaType(*pMediaType); + freeMediaType(*pMediaType); return false; } @@ -661,7 +661,7 @@ if ( mapDirectShowMediaTypeToVidcapFourcc( pMediaType->subtype.Data1, nativeFourcc) ) { - dshowMgr_->freeMediaType(*pMediaType); + freeMediaType(*pMediaType); return false; } @@ -671,7 +671,7 @@ { if ( conv_conversion_func_get(nativeFourcc, fmtNominal->fourcc) == 0 ) { - dshowMgr_->freeMediaType(*pMediaType); + freeMediaType(*pMediaType); return false; } } @@ -700,6 +700,16 @@ } void +DirectShowSource::freeMediaType(AM_MEDIA_TYPE &mediaType) const +{ + if ( mediaType.cbFormat != 0 ) + CoTaskMemFree((PVOID)mediaType.pbFormat); + + if ( mediaType.pUnk != NULL ) + mediaType.pUnk->Release(); +} + +void DirectShowSource::cancelCallbacks() { // serialize with normal capture callbacks @@ -721,7 +731,6 @@ stop(); } -// Fake out interface queries STDMETHODIMP DirectShowSource::QueryInterface(REFIID riid, void ** ppv) { @@ -737,8 +746,7 @@ return E_NOINTERFACE; } -// The sample grabber is calling us back on its deliver thread. -// This is NOT the main app thread! +// The sample grabber calls us back from its deliver thread STDMETHODIMP DirectShowSource::BufferCB( double dblSampleTime, BYTE * pBuff, long buffSize ) { Modified: trunk/src/directshow/DirectShowSource.h =================================================================== --- trunk/src/directshow/DirectShowSource.h 2007-09-11 18:43:51 UTC (rev 15) +++ trunk/src/directshow/DirectShowSource.h 2007-09-12 13:57:59 UTC (rev 16) @@ -47,8 +47,7 @@ void cancelCallbacks(); - const char * - getID() const + const char * getID() const { return sourceContext_->src_info.identifier; } @@ -63,21 +62,21 @@ bool findBestFormat(const vidcap_fmt_info * fmtNominal, vidcap_fmt_info * fmtNative, AM_MEDIA_TYPE **mediaFormat) const; - // Fake out COM reference counting + void freeMediaType(AM_MEDIA_TYPE &) const; + + // Fake out COM STDMETHODIMP_(ULONG) AddRef() { return 2; } STDMETHODIMP_(ULONG) Release() { return 1; } + STDMETHODIMP QueryInterface(REFIID riid, void ** ppv); - // Fake out interface querying - STDMETHODIMP - QueryInterface(REFIID riid, void ** ppv); + // Not used + STDMETHODIMP SampleCB( double SampleTime, IMediaSample * pSample ) + { + return S_OK; + } - // We don't implement this one + // The sample grabber calls us back from its deliver thread STDMETHODIMP - SampleCB( double SampleTime, IMediaSample * pSample ) { return S_OK; } - - // The sample grabber is calling us back on its deliver thread. - // This is NOT the main app thread - STDMETHODIMP BufferCB( double dblSampleTime, BYTE * pBuffer, long lBufferSize ); static int mapDirectShowMediaTypeToVidcapFourcc(DWORD data, int & fourcc); @@ -85,7 +84,6 @@ private: struct sapi_src_context * sourceContext_; DShowSrcManager * dshowMgr_; - IBaseFilter * pSource_; ICaptureGraphBuilder2 *pCapGraphBuilder_; IAMStreamConfig * pStreamConfig_; @@ -94,11 +92,8 @@ IBaseFilter * pSampleGrabber_; ISampleGrabber * pSampleGrabberIF_; IBaseFilter * pNullRenderer_; - IMediaControl * pMediaControlIF_; - AM_MEDIA_TYPE *nativeMediaType_; - CRITICAL_SECTION captureMutex_; bool stoppingCapture_; }; 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-11 15:31:21
|
Revision: 14 http://libvidcap.svn.sourceforge.net/libvidcap/?rev=14&view=rev Author: bcholew Date: 2007-09-11 08:31:16 -0700 (Tue, 11 Sep 2007) Log Message: ----------- Remove all destination buffer size checks in conversion functions. Replace with notices for each class of conversion function. Modified Paths: -------------- trunk/examples/vidcapTester/Grabber.cpp trunk/include/vidcap/converters.h trunk/src/conv.c trunk/src/conv.h trunk/src/conv_to_i420.c trunk/src/conv_to_rgb.c trunk/src/conv_to_yuy2.c trunk/src/sapi.c Modified: trunk/examples/vidcapTester/Grabber.cpp =================================================================== --- trunk/examples/vidcapTester/Grabber.cpp 2007-09-11 14:46:28 UTC (rev 13) +++ trunk/examples/vidcapTester/Grabber.cpp 2007-09-11 15:31:16 UTC (rev 14) @@ -134,13 +134,13 @@ rgb_buf.resize(width_ * height_ * 4); vidcap_i420_to_rgb32(width_, height_, cap_info->video_data, - rgb_buf.data(), rgb_buf.size()); + rgb_buf.data()); break; case VIDCAP_FOURCC_YUY2: rgb_buf.resize(width_ * height_ * 4); vidcap_yuy2_to_rgb32(width_, height_, cap_info->video_data, - rgb_buf.data(), rgb_buf.size()); + rgb_buf.data()); break; Modified: trunk/include/vidcap/converters.h =================================================================== --- trunk/include/vidcap/converters.h 2007-09-11 14:46:28 UTC (rev 13) +++ trunk/include/vidcap/converters.h 2007-09-11 15:31:16 UTC (rev 14) @@ -32,27 +32,27 @@ int vidcap_i420_to_rgb32(int width, int height, const char * src, - char * dest, int dest_size); + char * dest); int vidcap_i420_to_yuy2(int width, int height, const char * src, - char * dest, int dest_size); + char * dest); int vidcap_yuy2_to_i420(int width, int height, const char * src, - char * dest, int dest_size); + char * dest); int vidcap_yuy2_to_rgb32(int width, int height, const char * src, - char * dest, int dest_size); + char * dest); int vidcap_rgb32_to_i420(int width, int height, const char * src, - char * dest, int dest_size); + char * dest); int vidcap_rgb32_to_yuy2(int width, int height, const char * src, - char * dest, int dest_size); + char * dest); #ifdef __cplusplus } Modified: trunk/src/conv.c =================================================================== --- trunk/src/conv.c 2007-09-11 14:46:28 UTC (rev 13) +++ trunk/src/conv.c 2007-09-11 15:31:16 UTC (rev 14) @@ -25,11 +25,11 @@ #include "conv.h" -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); -int conv_bottom_up_rgb24_to_rgb32(int w, int h, const char * s, char * d, int ds); +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); +int conv_rgb24_to_rgb32(int w, int h, const char * s, char * d); +int conv_yvu9_to_i420(int w, int h, const char * s, char * d); +int conv_bottom_up_rgb24_to_rgb32(int w, int h, const char * s, char * d); struct conv_info { Modified: trunk/src/conv.h =================================================================== --- trunk/src/conv.h 2007-09-11 14:46:28 UTC (rev 13) +++ trunk/src/conv.h 2007-09-11 15:31:16 UTC (rev 14) @@ -39,7 +39,7 @@ }; typedef int (*conv_func)(int width, int height, - const char * src, char * dst, int dst_size); + 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 14:46:28 UTC (rev 13) +++ trunk/src/conv_to_i420.c 2007-09-11 15:31:16 UTC (rev 14) @@ -27,10 +27,13 @@ #include <vidcap/converters.h> #include "logging.h" +/* NOTE: size of dest must be >= width * height * 3 / 2 + */ + int vidcap_rgb32_to_i420(int width, int height, const char * src, - char * dst, int dest_size) + char * dst) { log_error("vidcap_rgb32_to_i420() not implemented\n"); return -1; @@ -39,7 +42,7 @@ int vidcap_yuy2_to_i420(int width, int height, const char * src, - char * dst, int dest_size) + char * dst) { /* convert from a packed structure to a planar structure */ char * dst_y_even = dst; @@ -51,9 +54,6 @@ int i, j; - if ( dest_size < width * height * 3 / 2 ) - return -1; - /* yuy2 has a vertical sampling period (for u and v) * half that for i420. Will toss half of the * U and V data during repackaging. @@ -88,7 +88,7 @@ int conv_2vuy_to_i420(int width, int height, const char * src, - char * dst, int dest_size) + char * dst) { char * dst_y_even = dst; char * dst_y_odd = dst + width; @@ -99,9 +99,6 @@ int i, j; - if ( dest_size < width * height * 3 / 2 ) - return -1; - for ( i = 0; i < height / 2; ++i ) { for ( j = 0; j < width / 2; ++j ) @@ -132,7 +129,7 @@ int conv_yvu9_to_i420(int width, int height, const char * src, - char * dst, int dest_size) + char * dst) { char * dst_y = dst; char * dst_u_even = dst + width * height; @@ -145,9 +142,6 @@ 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 ) Modified: trunk/src/conv_to_rgb.c =================================================================== --- trunk/src/conv_to_rgb.c 2007-09-11 14:46:28 UTC (rev 13) +++ trunk/src/conv_to_rgb.c 2007-09-11 15:31:16 UTC (rev 14) @@ -23,7 +23,6 @@ * */ -//#include <string.h> #include <vidcap/converters.h> enum { @@ -98,9 +97,13 @@ * * Based on the formulas found at http://en.wikipedia.org/wiki/YUV */ + +/* NOTE: size of dest buffer must be >= width * height * 4 + */ + int vidcap_i420_to_rgb32(int width, int height, const char * src, - char * dest, int dest_size) + char * dest) { const unsigned char * y_even; const unsigned char * y_odd; @@ -110,9 +113,6 @@ unsigned int *dst_odd; int i, j; - if ( dest_size < width * height * 4 ) - return -1; - if ( !tables_initialized ) init_yuv2rgb_tables(); @@ -159,14 +159,11 @@ * 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 dest_size) + char * dest) { unsigned int * d = (unsigned int *)dest; int i, j; - if ( dest_size < width * height * 4 ) - return -1; - if ( !tables_initialized ) init_yuv2rgb_tables(); @@ -193,14 +190,11 @@ } int conv_rgb24_to_rgb32(int width, int height, const char * src, - char * dest, int dest_size) + char * dest) { 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; @@ -214,15 +208,12 @@ int conv_bottom_up_rgb24_to_rgb32(int width, int height, const char * src, - char * dest, int dest_size) + char * dest) { 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; Modified: trunk/src/conv_to_yuy2.c =================================================================== --- trunk/src/conv_to_yuy2.c 2007-09-11 14:46:28 UTC (rev 13) +++ trunk/src/conv_to_yuy2.c 2007-09-11 15:31:16 UTC (rev 14) @@ -26,9 +26,12 @@ #include <vidcap/converters.h> #include "logging.h" +/* NOTE: size of dest buffer must be >= width * height * 2 + */ + int vidcap_rgb32_to_yuy2(int width, int height, const char * src, - char * dest, int dest_size) + char * dest) { log_error("vidcap_rgb32_to_yuy2() not implemented\n"); return -1; @@ -36,7 +39,7 @@ int vidcap_i420_to_yuy2(int width, int height, const char * src, - char * dest, int dest_size) + char * dest) { log_error("vidcap_i420_to_yuy2() not implemented\n"); return -1; @@ -44,15 +47,12 @@ int conv_2vuy_to_yuy2(int width, int height, const char * src, - char * dest, int dest_size) + char * dest) { int i; 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/sapi.c =================================================================== --- trunk/src/sapi.c 2007-09-11 14:46:28 UTC (rev 13) +++ trunk/src/sapi.c 2007-09-11 15:31:16 UTC (rev 14) @@ -236,8 +236,7 @@ src_ctx->fmt_nominal.width, src_ctx->fmt_nominal.height, video_data, - src_ctx->fmt_conv_buf, - src_ctx->fmt_conv_buf_size) ) + src_ctx->fmt_conv_buf) ) { log_error("failed format conversion\n"); cap_info.error_status = -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-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 13:29:48
|
Revision: 12 http://libvidcap.svn.sourceforge.net/libvidcap/?rev=12&view=rev Author: bcholew Date: 2007-09-11 06:29:44 -0700 (Tue, 11 Sep 2007) Log Message: ----------- Re-org validateFormat() to be sure to return the best native format for a given nominal format. Tidy up. Modified Paths: -------------- trunk/src/directshow/DirectShowSource.cpp trunk/src/directshow/DirectShowSource.h Modified: trunk/src/directshow/DirectShowSource.cpp =================================================================== --- trunk/src/directshow/DirectShowSource.cpp 2007-09-11 13:15:47 UTC (rev 11) +++ trunk/src/directshow/DirectShowSource.cpp 2007-09-11 13:29:44 UTC (rev 12) @@ -372,12 +372,63 @@ } int +DirectShowSource::validateFormat(const vidcap_fmt_info * fmtNominal, + vidcap_fmt_info * fmtNative) const +{ + AM_MEDIA_TYPE *mediaFormat; + + if ( !findBestFormat(fmtNominal, fmtNative, &mediaFormat) ) + return 0; + + dshowMgr_->freeMediaType(*mediaFormat); + return 1; +} + +int DirectShowSource::bindFormat(const vidcap_fmt_info * fmtNominal) { + vidcap_fmt_info fmtNative; + // If we've already got one, free it if ( nativeMediaType_ ) + { dshowMgr_->freeMediaType(*nativeMediaType_); + nativeMediaType_ = 0; + } + if ( !findBestFormat(fmtNominal, &fmtNative, &nativeMediaType_) ) + return 1; + + // set the framerate + VIDEOINFOHEADER * vih = (VIDEOINFOHEADER *) nativeMediaType_->pbFormat; + vih->AvgTimePerFrame = 10000000 * + fmtNative.fps_denominator / + fmtNative.fps_numerator; + + // set the dimensions + vih->bmiHeader.biWidth = fmtNative.width; + vih->bmiHeader.biHeight = fmtNative.height; + + // set the stream's media type + HRESULT hr = pStreamConfig_->SetFormat(nativeMediaType_); + if ( FAILED(hr) ) + { + log_error("failed setting stream format (%d)\n", hr); + + dshowMgr_->freeMediaType(*nativeMediaType_); + nativeMediaType_ = 0; + + return 1; + } + + return 0; +} + +bool +DirectShowSource::findBestFormat(const vidcap_fmt_info * fmtNominal, + vidcap_fmt_info * fmtNative, AM_MEDIA_TYPE **mediaFormat) const + +{ bool needsFpsEnforcement = false; bool needsFmtConv = false; @@ -389,7 +440,7 @@ { log_error("capabilities struct is wrong size (%d not %d)\n", iSize, sizeof(VIDEO_STREAM_CONFIG_CAPS)); - return 1; + return false; } struct formatProperties @@ -400,12 +451,11 @@ AM_MEDIA_TYPE *mediaFormat; }; + // these will be filled-in by checkFormat() struct formatProperties * candidateFmtProps = new struct formatProperties [iCount]; + vidcap_fmt_info * fmtsNative = new vidcap_fmt_info [iCount]; - // these will be filled-in by checkFormat() - vidcap_fmt_info * fmtNative = new vidcap_fmt_info [iCount]; - // enumerate each NATIVE source format bool itCanWork = false; for (int iFormat = 0; iFormat < iCount; ++iFormat ) @@ -416,7 +466,7 @@ candidateFmtProps[iFormat].mediaFormat = 0; // evaluate each native source format - if ( checkFormat(fmtNominal, &fmtNative[iFormat], iFormat, + if ( checkFormat(fmtNominal, &fmtsNative[iFormat], iFormat, &(candidateFmtProps[iFormat].needsFmtConversion), &(candidateFmtProps[iFormat].needsFpsEnforcement), &(candidateFmtProps[iFormat].mediaFormat)) ) @@ -426,10 +476,6 @@ } } - // NOTE: Will need to free unselected mediaFormats - // before returning, but hold onto the best - // (if any) candidate format - // Can ANY of this source's native formats // satisfy the requested format (to be bound)? if ( !itCanWork ) @@ -448,9 +494,7 @@ !candidateFmtProps[iFmt].needsFmtConversion && !candidateFmtProps[iFmt].needsFpsEnforcement ) { - // found a perfect match! - log_info("bindFormat: found a 'perfect' match (fmt #%d)\n", iFmt); - + // found a perfect match bestFmtNum = iFmt; goto freeThenReturn; } @@ -464,8 +508,6 @@ candidateFmtProps[iFmt].needsFpsEnforcement ) { // found an okay match - log_info("bindFormat: found an 'okay' match (fmt #%d)\n", iFmt); - bestFmtNum = iFmt; goto freeThenReturn; } @@ -479,29 +521,23 @@ !candidateFmtProps[iFmt].needsFpsEnforcement ) { // found a so-so match - log_info("bindFormat: found a 'so-so' match (fmt #%d)\n", iFmt); - bestFmtNum = iFmt; goto freeThenReturn; } } - // any that work with both caveats? + // any that work at all (with both conversions)? for ( int iFmt = 0; iFmt < iCount; ++iFmt ) { - if ( candidateFmtProps[iFmt].isSufficient && - candidateFmtProps[iFmt].needsFmtConversion && - candidateFmtProps[iFmt].needsFpsEnforcement ) + if ( candidateFmtProps[iFmt].isSufficient ) { // found a poor match - log_info("bindFormat: found a poor match (fmt #%d)\n", iFmt); - bestFmtNum = iFmt; goto freeThenReturn; } } - log_error("bindFormat: coding ERROR\n"); + log_error("findBestFormat: coding ERROR\n"); itCanWork = false; freeThenReturn: @@ -520,84 +556,24 @@ // Can bind succeed? if ( itCanWork ) { - // take note of native media type, fps, dimensions - nativeMediaType_ = candidateFmtProps[bestFmtNum].mediaFormat; + // take note of native media type, fps, dimensions, fourcc + *mediaFormat = candidateFmtProps[bestFmtNum].mediaFormat; - // 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; + fmtNative->fps_numerator = + fmtsNative[bestFmtNum].fps_numerator; + fmtNative->fps_denominator = + fmtsNative[bestFmtNum].fps_denominator; + fmtNative->width = fmtsNative[bestFmtNum].width; + fmtNative->height = fmtsNative[bestFmtNum].height; + fmtNative->fourcc = fmtsNative[bestFmtNum].fourcc; } delete [] candidateFmtProps; - delete [] fmtNative; + delete [] fmtsNative; - if ( !itCanWork ) - return 1; - - return 0; + return itCanWork; } -bool -DirectShowSource::validateFormat(const vidcap_fmt_info * fmtNominal, - vidcap_fmt_info * fmtNative) const -{ - bool needsFpsEnforcement = false; - bool needsFmtConv = false; - - int iCount = 0, iSize = 0; - HRESULT hr = pStreamConfig_->GetNumberOfCapabilities(&iCount, &iSize); - - // Check the size to make sure we pass in the correct structure. - if (iSize != sizeof(VIDEO_STREAM_CONFIG_CAPS) ) - { - log_error("capabilities struct is wrong size (%d not %d)\n", - iSize, sizeof(VIDEO_STREAM_CONFIG_CAPS)); - return 0; - } - - // enumerate each NATIVE format for this source - bool itWorks = false; - for (int iFormat = 0; iFormat < iCount; iFormat++) - { - AM_MEDIA_TYPE *mediaFormat = 0; - - itWorks = checkFormat(fmtNominal, fmtNative, iFormat, - &needsFpsEnforcement, &needsFmtConv, - &mediaFormat); - - if ( itWorks ) - { - dshowMgr_->freeMediaType(*mediaFormat); - return 1; - } - } - - return 0; -} - // Evaluate one of perhaps several native formats for // suitability for providing the nominal format. // Fill-in output parameter 'mediaFormat'. @@ -698,12 +674,10 @@ dshowMgr_->freeMediaType(*pMediaType); return false; } - - fmtNative->fourcc = nativeFourcc; } - else - fmtNative->fourcc = fmtNominal->fourcc; + fmtNative->fourcc = nativeFourcc; + fmtNative->width = fmtNominal->width; fmtNative->height = fmtNominal->height; Modified: trunk/src/directshow/DirectShowSource.h =================================================================== --- trunk/src/directshow/DirectShowSource.h 2007-09-11 13:15:47 UTC (rev 11) +++ trunk/src/directshow/DirectShowSource.h 2007-09-11 13:29:44 UTC (rev 12) @@ -42,7 +42,7 @@ int start(); int stop(); int bindFormat(const vidcap_fmt_info * fmtInfo); - bool validateFormat(const vidcap_fmt_info * fmtNominal, + int validateFormat(const vidcap_fmt_info * fmtNominal, vidcap_fmt_info * fmtNative) const; void cancelCallbacks(); @@ -60,6 +60,9 @@ bool *needsFramerateEnforcing, bool *needsFormatConversion, AM_MEDIA_TYPE **candidateMediaFormat) const; + bool findBestFormat(const vidcap_fmt_info * fmtNominal, + vidcap_fmt_info * fmtNative, AM_MEDIA_TYPE **mediaFormat) const; + // Fake out COM reference counting STDMETHODIMP_(ULONG) AddRef() { return 2; } STDMETHODIMP_(ULONG) Release() { 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-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-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-07 21:53:32
|
Revision: 9 http://libvidcap.svn.sourceforge.net/libvidcap/?rev=9&view=rev Author: bcholew Date: 2007-09-07 14:53:30 -0700 (Fri, 07 Sep 2007) Log Message: ----------- Removed unused code: functions canConvertToRGB32(), getMediaType(), buildFormatList(), and member variables pSourceOutPin_, pIntermediateFilter_ and intermediateMediaType_. Modified Paths: -------------- trunk/src/directshow/DirectShowSource.cpp trunk/src/directshow/DirectShowSource.h Modified: trunk/src/directshow/DirectShowSource.cpp =================================================================== --- trunk/src/directshow/DirectShowSource.cpp 2007-09-07 21:33:40 UTC (rev 8) +++ trunk/src/directshow/DirectShowSource.cpp 2007-09-07 21:53:30 UTC (rev 9) @@ -51,8 +51,6 @@ pNullRenderer_(0), pMediaControlIF_(0), nativeMediaType_(0), - pIntermediateFilter_(0), - intermediateMediaType_(0), stoppingCapture_(false) { if ( !dshowMgr_ ) @@ -93,14 +91,6 @@ goto constructionFailure; } -#if 0 - if ( !buildFormatList(pBindCtx, pMoniker) ) - { - log_warn("Failed building format list for '%s'.\n", getID()); - goto constructionFailure; - } -#else - hr = CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL, CLSCTX_INPROC_SERVER, @@ -125,18 +115,7 @@ pCapGraphBuilder_->Release(); goto constructionFailure; } -#endif - // FIXME: does this really need to be a member? Maybe should be in start(). - pSourceOutPin_ = dshowMgr_->getOutPin( pSource_, 0 ); - - if ( !pSourceOutPin_ ) - { - log_error("Failed getting source output pin\n"); - goto constructionFailure; - } - - hr = CoCreateInstance(CLSID_FilterGraph, 0, CLSCTX_INPROC_SERVER, @@ -202,8 +181,6 @@ pFilterGraph_->Release(); - pSourceOutPin_.Release(); - pSource_->Release(); pStreamConfig_->Release(); @@ -215,316 +192,7 @@ DeleteCriticalSection(&captureMutex_); } -#if 0 int -DirectShowSource::buildFormatList(IBindCtx * pBindCtx, IMoniker * pMoniker) -{ - HRESULT hr = CoCreateInstance(CLSID_CaptureGraphBuilder2, - NULL, - CLSCTX_INPROC_SERVER, - IID_ICaptureGraphBuilder2, - (void **)&pCapGraphBuilder_); - - if ( FAILED(hr) ) - { - log_error("failed creating capture graph builder (%d)\n", hr); - return 0; - } - - hr = pCapGraphBuilder_->FindInterface(&PIN_CATEGORY_CAPTURE, - &MEDIATYPE_Video, - pSource_, - IID_IAMStreamConfig, - (void **)&pStreamConfig_); - if( FAILED(hr) ) - { - log_error("failed getting stream config " - "while building format list (%d)\n", hr); - pCapGraphBuilder_->Release(); - return 0; - } - - int iCount = 0, iSize = 0; - hr = pStreamConfig_->GetNumberOfCapabilities(&iCount, &iSize); - - // Check the size to make sure we pass in the correct structure. - if (iSize != sizeof(VIDEO_STREAM_CONFIG_CAPS) ) - { - log_error("capabilities struct is wrong size (%d not %d)\n", - iSize, sizeof(VIDEO_STREAM_CONFIG_CAPS)); - pStreamConfig_->Release(); - pCapGraphBuilder_->Release(); - return 0; - } - - // enumerate each source format - for (int iFormat = 0; iFormat < iCount; iFormat++) - { - // get the video stream capabilities structure - VIDEO_STREAM_CONFIG_CAPS scc; - AM_MEDIA_TYPE *pMediaType; - hr = pStreamConfig_->GetStreamCaps(iFormat, &pMediaType, - (BYTE*)&scc); - - if (FAILED(hr)) - { - log_warn("failed getting stream capabilities [%d of %d] (%d)\n", - iFormat+1, iCount, hr); - continue; - } - - int fourcc; - - if ( mapDirectShowMediaTypeToVidcapFourcc( - pMediaType->subtype.Data1, fourcc) ) - continue; - - // calculate range of supported frame rates - double fpsMin = static_cast<double>( 1000000000 / scc.MaxFrameInterval) - / 100.0; - double fpsMax = static_cast<double>( 1000000000 / scc.MinFrameInterval) - / 100.0; - - // enumerate a format for each frame rate - for ( int i = 0; i < hot_fps_list_len; ++i ) - { - int hot_fps_num = hot_fps_list[i].fps_numerator; - int hot_fps_den = hot_fps_list[i].fps_denominator; - double fps = static_cast<double>(hot_fps_num) / - static_cast<double>(hot_fps_den); - - if ( fps < fpsMin || fps > fpsMax ) - continue; - - for ( int j = 0; j < hot_resolution_list_len; ++j ) - { - vidcap_fmt_info * fmt; - - const int hot_width = - hot_resolution_list[j].width; - const int hot_height = - hot_resolution_list[j].height; - - if ( hot_width < scc.MinOutputSize.cx || - hot_height < scc.MinOutputSize.cy || - hot_width > scc.MaxOutputSize.cx || - hot_height > scc.MaxOutputSize.cy ) - { - continue; - } - - fmtListLen_++; - pFmtList_ = static_cast<vidcap_fmt_info *>( - realloc(pFmtList_, - fmtListLen_ * - sizeof(vidcap_fmt_info))); - - if ( !pFmtList_ ) - { - log_error("failed reallocating format list\n"); - - dshowMgr_->freeMediaType(*pMediaType); - pStreamConfig_->Release(); - pCapGraphBuilder_->Release(); - return 0; - } - - fmt = &pFmtList_[fmtListLen_ - 1]; - - fmt->width = hot_width; - fmt->height = hot_height; - fmt->fourcc = fourcc; - fmt->fps_numerator = hot_fps_num; - fmt->fps_denominator = hot_fps_den; - - // TODO: revisit OutputGranularity if a device - // is found that uses it - } - } - - dshowMgr_->freeMediaType(*pMediaType); - } - - return fmtListLen_; -} -#endif - -bool -DirectShowSource::canConvertToRGB32() -{ - if ( pIntermediateFilter_ ) - pIntermediateFilter_->Release(); - - // used if format conversion is necessary - intermediateMediaType_ = 0; - pIntermediateFilter_ = 0; - - IFilterMapper2 *pMapper = NULL; - IEnumMoniker *pEnum = NULL; - - HRESULT hr; - hr = CoCreateInstance(CLSID_FilterMapper2, - NULL, - CLSCTX_INPROC, - IID_IFilterMapper2, - (void **) &pMapper); - - if (FAILED(hr)) - { - log_error("failed to create FilterMapper2 (%d)\n", hr); - return false; - } - - // search for a filter to convert to RGB32 - - GUID arrayInTypes[2]; - GUID arrayOutTypes[2]; - memset(&arrayInTypes[1], 0, sizeof(arrayInTypes[1])); - memset(&arrayOutTypes[1], 0, sizeof(arrayOutTypes[1])); - - CComPtr< IEnumMediaTypes > pMediaEnum; - hr = pSourceOutPin_->EnumMediaTypes(&pMediaEnum); - if ( FAILED(hr) ) - { - log_error("failed creating media type enumerator (rc=%d)\n", hr); - pMapper->Release(); - return false; - } - - // enumerate all media types of source - ULONG ulFound; - AM_MEDIA_TYPE * pMedia; - while ( S_OK == pMediaEnum->Next(1, &pMedia, &ulFound) ) - { - VIDEOINFOHEADER * vih = (VIDEOINFOHEADER *)pMedia->pbFormat; - - // find entry that matches desired format - if ( vih->bmiHeader.biWidth != sourceContext_->fmt_nominal.width || - vih->bmiHeader.biHeight != sourceContext_->fmt_nominal.height ) - { - // invalid dimensions - dshowMgr_->freeMediaType(*pMedia); - continue; - } - - arrayInTypes[0] = pMedia->majortype; - arrayInTypes[1] = pMedia->subtype; - - arrayOutTypes[0] = MEDIATYPE_Video; - arrayOutTypes[1] = MEDIASUBTYPE_RGB32; - -#if 0 - log_info("considering input format %c%c%c%c\n", - (arrayInTypes[1].Data1 >> 0) & 0xff, - (arrayInTypes[1].Data1 >> 8) & 0xff, - (arrayInTypes[1].Data1 >> 16) & 0xff, - (arrayInTypes[1].Data1 >> 24) & 0xff); -#endif - - IEnumMoniker *pFilterEnum = NULL; - hr = pMapper->EnumMatchingFilters( - &pFilterEnum, - 0, // Reserved. - TRUE, // Use exact match? - MERIT_DO_NOT_USE+1, // Minimum merit. - TRUE, // At least one input pin? - - 1, // # of major type/subtype pairs for input - arrayInTypes, // Array of major/subtype pairs for input - - NULL, // Input medium. - NULL, // Input pin category. - FALSE, // Must be a renderer? - TRUE, // At least one output pin? - - 1, // # of major type/subtype pairs for output - arrayOutTypes, // Array of major/subtype pairs for output - - NULL, // Output medium. - NULL); // Output pin category. - - // Enumerate the filter monikers - IMoniker *pMoniker; - ULONG cFetched; - while ( pFilterEnum->Next(1, &pMoniker, &cFetched) == S_OK ) - { - IPropertyBag *pPropBag = NULL; - hr = pMoniker->BindToStorage(0, 0, IID_IPropertyBag, - (void **)&pPropBag); - - if ( FAILED(hr) ) - { - log_warn("Couldn't bind to storage for this matching filter\n"); - pMoniker->Release(); - continue; - } - - // Get the friendly name of the filter - VARIANT varName; - VariantInit(&varName); - hr = pPropBag->Read(L"FriendlyName", &varName, 0); - if ( SUCCEEDED(hr) ) - { - char * pszFriendlyName = - _com_util::ConvertBSTRToString( - varName.bstrVal); - - log_info("conversion filter '%s' should work\n", - pszFriendlyName); - - delete [] pszFriendlyName; - } - VariantClear(&varName); - - // Create an instance of the filter - hr = pMoniker->BindToObject(NULL, - NULL, - IID_IBaseFilter, - (void**)&pIntermediateFilter_); - - if (FAILED(hr)) - { - //FIXME: name it - log_warn("failed to instantiate conversion filter (%d)\n", - hr); - - pPropBag->Release(); - pMoniker->Release(); - pIntermediateFilter_ = 0; - continue; - } - - // TODO: - // get output pin of intermediate filter? - // get it's media type? - - intermediateMediaType_ = arrayInTypes[1].Data1; - - pPropBag->Release(); - pMoniker->Release(); - pFilterEnum->Release(); - dshowMgr_->freeMediaType(*pMedia); - pMediaEnum.Release(); - pMapper->Release(); - - return true; - } - - // cleanup - pFilterEnum->Release(); - dshowMgr_->freeMediaType(*pMedia); - - // failed to find filter suitable to convert this media type to RGB32 - } - - pMediaEnum.Release(); - pMapper->Release(); - - // Can't build filter graph to convert this source's output to RGB32 - return false; -} - -int DirectShowSource::start() { HRESULT hr = pFilterGraph_->QueryInterface(IID_IMediaControl, @@ -604,19 +272,8 @@ } // Set sample grabber's media type to match that of the source - // OR the conversion filter - if ( intermediateMediaType_ ) - { - //FIXME: Shouldn't this be necessary? - pAmMediaType->subtype.Data1 = intermediateMediaType_; - //hr = pSampleGrabberIF_->SetMediaType(pAmMediaType); - hr = pSampleGrabberIF_->SetMediaType(NULL); - } - else - { - //FIXME: do at bind time - hr = pSampleGrabberIF_->SetMediaType(pAmMediaType); - } + //FIXME: do at bind time + hr = pSampleGrabberIF_->SetMediaType(pAmMediaType); if ( FAILED(hr) ) { log_error("failed to set grabber media type (%d)\n", hr); @@ -658,81 +315,17 @@ goto bail_5; } - if ( pIntermediateFilter_ ) + hr = pCapGraphBuilder_->RenderStream(&PIN_CATEGORY_CAPTURE, + &MEDIATYPE_Video, + pSource_, + pSampleGrabber_, + pNullRenderer_); + if ( FAILED(hr) ) { - hr = pFilterGraph_->AddFilter(pIntermediateFilter_, - L"ConversionFilter"); - if ( FAILED(hr) ) - { - log_error("failed to add conversion filter (%d)\n", hr); - goto bail_5; - } - - hr = pCapGraphBuilder_->RenderStream(NULL, //&PIN_CATEGORY_CAPTURE, - NULL, //&MEDIATYPE_Video, - pSource_, - pIntermediateFilter_, - pSampleGrabber_); - if ( FAILED(hr) ) - { - log_error("failed to connect source, conversion filter, " - "sample grabber (%lu 0x%x)\n", hr, hr); - switch ( hr ) - { - case VFW_S_NOPREVIEWPIN: - log_error("VFW_S_NOPREVIEWPIN\n"); - break; - - case E_FAIL: - log_error("E_FAIL\n"); - break; - - case E_POINTER: - log_error("E_POINTER\n"); - break; - - case VFW_E_NOT_IN_GRAPH: - log_error("VFW_E_NOT_IN_GRAPH\n"); - break; - - case E_INVALIDARG: - log_error("E_INVALIDARG\n"); - break; - - default: - log_error("default\n"); - break; - } - goto bail_5; - } - - hr = pCapGraphBuilder_->RenderStream( - NULL, //&PIN_CATEGORY_CAPTURE, - NULL, //&MEDIATYPE_Video, - pSampleGrabber_, - NULL, - pNullRenderer_); - if ( FAILED(hr) ) - { - log_error("failed to connect grabber and null renderer (%d)\n", - hr); - goto bail_5; - } + log_error("failed to connect source, grabber " + "and null renderer (%d)\n", hr); + goto bail_5; } - else - { - hr = pCapGraphBuilder_->RenderStream(&PIN_CATEGORY_CAPTURE, - &MEDIATYPE_Video, - pSource_, - pSampleGrabber_, - pNullRenderer_); - if ( FAILED(hr) ) - { - log_error("failed to connect source, grabber " - "and null renderer (%d)\n", hr); - goto bail_5; - } - } hr = pMediaControlIF_->Run(); @@ -786,10 +379,6 @@ log_error("failed to STOP the filter graph (%ul)\n", hr); } - if ( pIntermediateFilter_ ) - pIntermediateFilter_->Release(); - pIntermediateFilter_ = 0; - if ( pNullRenderer_ ) pNullRenderer_->Release(); pNullRenderer_ = 0; @@ -1217,86 +806,6 @@ return ret; } -//FIXME: Is there a better way to get the media type -// from the width, height and fourcc? -AM_MEDIA_TYPE * -DirectShowSource::getMediaType( CComPtr< IPin > pPin) const -{ - CComPtr< IEnumMediaTypes > pEnum; - - HRESULT hr = pPin->EnumMediaTypes(&pEnum); - - if ( FAILED(hr) ) - { - log_error("failed creating media type enumerator (rc=%d)\n", hr); - return NULL; - } - - ULONG ulFound; - AM_MEDIA_TYPE * pMedia; - DWORD boundMediaType; - - if ( mapVidcapFourccToDirectShowMediaType( - sourceContext_->fmt_nominal.fourcc, - boundMediaType) ) - return NULL; - - int requiredMediaType = intermediateMediaType_ ? - intermediateMediaType_ : boundMediaType; - - while ( S_OK == pEnum->Next(1, &pMedia, &ulFound) ) - { - //printMediaFormatType(pMedia); - - VIDEOINFOHEADER * vih = - (VIDEOINFOHEADER *) pMedia->pbFormat; - int thisFourcc; - - if ( mapDirectShowMediaTypeToVidcapFourcc(pMedia->subtype.Data1, - thisFourcc) ) - continue; - - // find entry that matches desired format - if ( vih->bmiHeader.biWidth == - sourceContext_->fmt_nominal.width && - vih->bmiHeader.biHeight == - sourceContext_->fmt_nominal.height && - (thisFourcc == - sourceContext_->fmt_nominal.fourcc || - pMedia->subtype.Data1 == requiredMediaType) ) - { - return pMedia; - } - - dshowMgr_->freeMediaType(*pMedia); - } - - return NULL; -} - -void -DirectShowSource::printMediaFormatType(AM_MEDIA_TYPE *pMedia) -{ - if ( pMedia->formattype == FORMAT_DvInfo ) - log_info("FORMAT_DvInfo\n"); - else if ( pMedia->formattype == FORMAT_MPEG2Video ) - log_info("FORMAT_MPEG2Video\n"); - else if ( pMedia->formattype == FORMAT_MPEGStreams ) - log_info("FORMAT_MPEGStreams\n"); - else if ( pMedia->formattype == FORMAT_MPEGVideo ) - log_info("FORMAT_MPEGVideo\n"); - else if ( pMedia->formattype == FORMAT_None ) - log_info("FORMAT_None\n"); - else if ( pMedia->formattype == FORMAT_VideoInfo ) - log_info("FORMAT_VideoInfo\n"); - else if ( pMedia->formattype == FORMAT_VideoInfo2 ) - log_info("FORMAT_VideoInfo2\n"); - else if ( pMedia->formattype == FORMAT_WaveFormatEx ) - log_info("FORMAT_WaveFormatEx\n"); - else - log_info("unknown\n"); -} - int DirectShowSource::mapDirectShowMediaTypeToVidcapFourcc(DWORD data, int & fourcc) { Modified: trunk/src/directshow/DirectShowSource.h =================================================================== --- trunk/src/directshow/DirectShowSource.h 2007-09-07 21:33:40 UTC (rev 8) +++ trunk/src/directshow/DirectShowSource.h 2007-09-07 21:53:30 UTC (rev 9) @@ -54,17 +54,12 @@ } private: - bool canConvertToRGB32(); bool checkFormat(const vidcap_fmt_info * fmtNominal, vidcap_fmt_info * fmtNative, int formatNum, bool *needsFramerateEnforcing, bool *needsFormatConversion, AM_MEDIA_TYPE **candidateMediaFormat) const; - // NOTE: this will soon be obsolete - AM_MEDIA_TYPE * getMediaType( CComPtr< IPin > pPin) const; - void printMediaFormatType(AM_MEDIA_TYPE *pMedia); - // Fake out COM reference counting STDMETHODIMP_(ULONG) AddRef() { return 2; } STDMETHODIMP_(ULONG) Release() { return 1; } @@ -90,7 +85,6 @@ DShowSrcManager * dshowMgr_; IBaseFilter * pSource_; - CComPtr<IPin> pSourceOutPin_; // TODO: remove CComPtr ICaptureGraphBuilder2 *pCapGraphBuilder_; IAMStreamConfig * pStreamConfig_; IGraphBuilder *pFilterGraph_; @@ -103,11 +97,6 @@ AM_MEDIA_TYPE *nativeMediaType_; - // when necessary to convert source output format - //NOTE: these two will soon be obsolete - IBaseFilter *pIntermediateFilter_; - DWORD intermediateMediaType_; - CRITICAL_SECTION captureMutex_; bool stoppingCapture_; }; 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-07 21:33:44
|
Revision: 8 http://libvidcap.svn.sourceforge.net/libvidcap/?rev=8&view=rev Author: bcholew Date: 2007-09-07 14:33:40 -0700 (Fri, 07 Sep 2007) Log Message: ----------- DirectShow-specific release function should only cleanup DirectShow-specific stuff. Generic layer frees the source context. Modified Paths: -------------- trunk/src/sapi_dshow.cpp Modified: trunk/src/sapi_dshow.cpp =================================================================== --- trunk/src/sapi_dshow.cpp 2007-09-07 21:24:00 UTC (rev 7) +++ trunk/src/sapi_dshow.cpp 2007-09-07 21:33:40 UTC (rev 8) @@ -126,7 +126,7 @@ source_release(struct sapi_src_context * src_ctx) { delete static_cast<DirectShowSource *>(src_ctx->priv); - delete src_ctx; + 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-07 21:24:05
|
Revision: 7 http://libvidcap.svn.sourceforge.net/libvidcap/?rev=7&view=rev Author: bcholew Date: 2007-09-07 14:24:00 -0700 (Fri, 07 Sep 2007) Log Message: ----------- Fix color mismatch and saturation problems in rgb24-to-rgb32 conversion. Modified Paths: -------------- trunk/src/conv_to_rgb.c Modified: trunk/src/conv_to_rgb.c =================================================================== --- trunk/src/conv_to_rgb.c 2007-09-07 21:21:27 UTC (rev 6) +++ trunk/src/conv_to_rgb.c 2007-09-07 21:24:00 UTC (rev 7) @@ -197,9 +197,9 @@ for ( i = 0; i < width * height; ++i ) { *d = 0xff000000; - *d |= (*src++) << 16; - *d |= (*src++) << 8; - *d++ |= (*src++); + *d |= ((unsigned char)(*src++)); // blue + *d |= ((unsigned char)(*src++)) << 8; // green + *d++ |= ((unsigned char)(*src++)) << 16; // red } return 0; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |