From Cedric Pinson, "Here an update of the directshow plugin. It fixes issues with

synchronization, improve capture device support.

here how to use it to display a capture device:

osg::Options* options = new osg::Options;
options->setPluginStringData("captureWantedWidth", "800");
options->setPluginStringData("captureWantedHeight", "600");
options->setPluginStringData("captureWantedFps", "30");
options->setPluginStringData("captureVideoDevice", "USB Video Device" );
options->setPluginStringData("captureSoundDevice", "");
then
osgDB::readImageFile("capture.directshow", options)
you can use a graphedit application to list devices available in
directshow.


for classic avi file you just need to do a
osgDB::readImageFile("file.avi.directshow");
You will need of course to install the codec needed by directshow to
read the avi files.

I recommand this tool http://avicodec.duby.info/, that check which
video/sound codec is needed to play an avi file.


You can test it with the osgmovie example.
"
This commit is contained in:
Robert Osfield 2009-11-20 10:48:51 +00:00
parent f45ae6a4d8
commit 7552954ef3
7 changed files with 2222 additions and 0 deletions

View File

@ -363,6 +363,7 @@ FIND_PACKAGE(OurDCMTK)
FIND_PACKAGE(OpenAL) FIND_PACKAGE(OpenAL)
FIND_PACKAGE(XUL) FIND_PACKAGE(XUL)
FIND_PACKAGE(FFmpeg) FIND_PACKAGE(FFmpeg)
FIND_PACKAGE(DirectShow)
FIND_PACKAGE(SDL) FIND_PACKAGE(SDL)
#use pkg-config to find various modues #use pkg-config to find various modues

View File

@ -0,0 +1,58 @@
# Locate directshow
# This module defines
# DIRECTSHOW_LIBRARIES
# DIRECTSHOW_FOUND, if false, do not try to link to directshow
# DIRECTSHOW_INCLUDE_DIR, where to find the headers
#
# $DIRECTSHOW_DIR is an environment variable that would
# point to the this path in the plateform devkit (Samples\Multimedia\DirectShow)
#
# Created by Cedric Pinson.
#
SET(DIRECTSHOW_FOUND "NO")
SET(DIRECTSHOW_SAMPLE_ROOT "$ENV{DIRECTSHOW_DIR}" CACHE PATH "Location of DirectShow sample in devkit")
IF(WIN32)
FIND_PATH(DIRECTSHOW_STRMBASE_INCLUDE_DIRS renbase.h
PATHS
${DIRECTSHOW_SAMPLE_ROOT}/BaseClasses/
$ENV{DIRECTSHOW_SAMPLE_ROOT}/BaseClasses/
DOC "Location of DirectShow Base include on the windows devkit"
)
FIND_LIBRARY(DIRECTSHOW_STRMBASE_LIBRARY_RELEASE strmbase
PATHS
${DIRECTSHOW_SAMPLE_ROOT}/BaseClasses/Release_MBCS/ # sdk 6.1
$ENV{DIRECTSHOW_SAMPLE_ROOT}/BaseClasses/Release_MBCS/ # sdk 6.1
${DIRECTSHOW_SAMPLE_ROOT}/BaseClasses/Release/ # sdk 2003
$ENV{DIRECTSHOW_SAMPLE_ROOT}/BaseClasses/Release/ # sdk 2003
DOC "Location of DirectShow Base library on the windows devkit"
)
FIND_LIBRARY(DIRECTSHOW_STRMBASE_LIBRARY_DEBUG strmbasd
PATHS
${DIRECTSHOW_SAMPLE_ROOT}/BaseClasses/Debug_MBCS/ # sdk 6.1
$ENV{DIRECTSHOW_SAMPLE_ROOT}/BaseClasses/Debug_MBCS/ # sdk 6.1
${DIRECTSHOW_SAMPLE_ROOT}/BaseClasses/Debug/ # sdk 2003
$ENV{DIRECTSHOW_SAMPLE_ROOT}/BaseClasses/Debug/ # sdk 2003
DOC "Location of DirectShow Base library on the windows devkit"
)
IF (DIRECTSHOW_STRMBASE_INCLUDE_DIRS AND DIRECTSHOW_STRMBASE_LIBRARY_RELEASE)
SET(WIN_LIBS winmm d3d9 d3dx9 kernel32 user32 gdi32 winspool shell32 ole32 oleaut32 uuid comdlg32 advapi32)
SET(DIRECTSHOW_FOUND "YES")
SET(DIRECTSHOW_LIBRARY_DEBUG
${DIRECTSHOW_STRMBASE_LIBRARY_DEBUG}
)
SET(DIRECTSHOW_LIBRARY
${DIRECTSHOW_STRMBASE_LIBRARY_RELEASE}
)
SET(DIRECTSHOW_INLUDE_DIRS
${DIRECTSHOW_STRMBASE_INCLUDE_DIRS}
)
ENDIF()
ENDIF()

View File

@ -208,6 +208,10 @@ IF(FFMPEG_FOUND)
ADD_SUBDIRECTORY(ffmpeg) ADD_SUBDIRECTORY(ffmpeg)
ENDIF() ENDIF()
IF(DIRECTSHOW_FOUND)
ADD_SUBDIRECTORY(directshow)
ENDIF()
# IF(OPENAL_FOUND) # IF(OPENAL_FOUND)
# ADD_SUBDIRECTORY(OpenAL) # ADD_SUBDIRECTORY(OpenAL)
# ENDIF() # ENDIF()

View File

@ -0,0 +1,68 @@
# For visual studio express 2005 and windows plateforme sdk 2003
# i have some problem with the windows sdk to build the BaseClasses, so
# here some point that will help to fix this.
# https://blogs.msdn.com/mikewasson/archive/2005/05/23/421116.aspx
# use this link to downloads vc project to build strmbase library
# http://www.microsoft.com/downloads/thankyou.aspx?familyId=8af0afa9-1383-44b4-bc8b-7d6315212323&displayLang=en
# to build strmbase.lib
# modify clutil.h line 278
# operator=(LONG);
# to
# (LONG) operator=(LONG);
# add in includes directory
# C:\Program Files\Microsoft Platform SDK for Windows Server 2003 R2\Include\atl
# modify winutil.cpp line 2104
# for (Count = 0;Count < Result;Count++) {
# to
# for (UINT Count = 0;Count < Result;Count++) {
# modify winutil.cpp line 2123
# for (Count = PalLoCount;INT(Count) < min(PalHiStart,iColours);Count++) {
# to
# for (UINT Count = PalLoCount;INT(Count) < min(PalHiStart,iColours);Count++) {
# modify wxdebug.cpp line 564
# static g_dwLastRefresh = 0;
# to
# static DWORD g_dwLastRefresh = 0;
# modify outputq.cpp line 6134
# LONG iLost = 0;
# for (long iDone = 0;
# to
# LONG iLost = 0;
# long iDone = 0;
# for (iDone = 0;
# In the properties of the project there is a fixed path to link with strmiids.lib. Replace the ../../../.. by the name of the library
# only, then the linker will find the strmiids.lib
# After those step it should compile, becareful using unicode version will result undefined symbol ... so use multibyte version instead
#
# End For visual studio express 2005 and windows plateforme sdk 2003
INCLUDE_DIRECTORIES( ${DIRECTSHOW_INLUDE_DIRS} )
SET (TARGET_EXTERNAL_LIBRARIES
quartz comsuppw winmm d3d9 d3dx9 kernel32 user32 gdi32 winspool shell32 ole32 oleaut32 uuid comdlg32 advapi32
)
SET(TARGET_SRC
ReaderWriterDirectShow.cpp
DirectShowTexture.cpp
)
SET(TARGET_H
DirectShowTexture
)
SET(TARGET_LIBRARIES_VARS DIRECTSHOW_LIBRARY )
#### end var setup ###
SETUP_PLUGIN(directshow directshow)
SET_TARGET_PROPERTIES("${TARGET_DEFAULT_PREFIX}${TARGET_NAME}" PROPERTIES LINK_FLAGS "/NODEFAULTLIB:atlthunk")

View File

@ -0,0 +1,125 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) 2009 Tharsis Software
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
* (at your option) any later version. The full license is in LICENSE file
* included with this distribution, and on the openscenegraph.org website.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details.
*
* Authors:
* Cedric Pinson <cedric.pinson@plopbyte.net>
*/
#ifndef DirectShowTexture
#define DirectShowTexture 1
#include <streams.h>
#include <map>
#include <osg/ImageStream>
#include <osg/observer_ptr>
#include <OpenThreads/Thread>
#include <OpenThreads/Mutex>
#include <OpenThreads/ScopedLock>
//-----------------------------------------------------------------------------
// Define GUID for Texture Renderer
// {71771540-2017-11cf-AE26-0020AFD79767}
//-----------------------------------------------------------------------------
struct __declspec(uuid("{71771540-2017-11cf-ae26-0020afd79767}")) CLSID_TextureRenderer;
class CTextureRenderer;
class DirectShowImageStream : public osg::ImageStream
{
public:
typedef std::map<std::string,std::string> Options;
protected:
osg::observer_ptr<CTextureRenderer> _renderer;
mutable OpenThreads::Mutex _mutex;
Options _options;
public:
DirectShowImageStream();
~DirectShowImageStream();
DirectShowImageStream(const DirectShowImageStream & image, const osg::CopyOp & copyop = osg::CopyOp::SHALLOW_COPY);
META_Object(osgDirectShow, DirectShowImageStream);
void run();
bool openFile(const std::string& file);
bool openCaptureDevices();
void setOptions(const Options& map);
void play();
void pause();
void rewind();
osg::ImageStream::StreamStatus getStatus();
void seek(double time);
double getLength() const;
double getFrameRate() const;
void setTimeMultiplier(double rate);
double getTimeMultiplier() const;
void quit(bool /*waitForThreadToExit*/ = true);
void stop();
};
//-----------------------------------------------------------------------------
// CTextureRenderer Class Declarations
//-----------------------------------------------------------------------------
class CTextureRenderer : public CBaseVideoRenderer, public osg::Referenced
{
public:
IGraphBuilder* _graphBuilder; // GraphBuilder
IMediaControl* _mediaControl; // Media Control
IMediaSeeking* _mediaSeeking; // Media seeking
IMediaEvent* _mediaEvent; // Media Event
IBaseFilter* _videoCaptureDevice;
IBaseFilter* _fileSource;
IBaseFilter* _soundOutputDevice;
IBaseFilter* _soundCaptureDevice;
HRESULT _dropFrame;
CTextureRenderer(DirectShowImageStream* imageStream, HRESULT* valid);
~CTextureRenderer();
void setFilename(const std::string& filename);
bool initBuildGraph();
bool initCaptureDevice();
bool openCaptureDevices(const DirectShowImageStream::Options& options);
bool openVideoCaptureDevice(const std::string& capture, int wantWidth, int wantHeight, double wantFps);
bool openSoundCaptureDevice(const std::string& capture, int nbChannels = 2);
bool openFile(const std::string& file);
bool startGraph();
void syncStreams(bool state);
bool setupOutputSoundDevice(ICreateDevEnum* devs);
void releaseRessources();
IGraphBuilder* getGraphBuilder() { return _graphBuilder; }
HRESULT ShouldDrawSampleNow(IMediaSample *sample, REFERENCE_TIME *start, REFERENCE_TIME *stop);
bool StopFilters();
HRESULT CheckMediaType(const CMediaType *pmt ); // Format acceptable?
HRESULT SetMediaType(const CMediaType *pmt ); // Video format notification
HRESULT DoRenderSample(IMediaSample *pMediaSample); // New video sample
int _width;
int _height;
int _pitch;
std::string _videoCaptureDeviceName;
std::string _soundCaptureDeviceName;
std::string _soundOutputDeviceName;
std::string _filename;
const std::string& getVideoCaptureDeviceName() const { return _videoCaptureDeviceName; }
const std::string& getSoundOutputDeviceName() const { return _soundOutputDeviceName; }
const std::string& getSoundCaptureDeviceName() const { return _soundCaptureDeviceName; }
const std::string& getFilename() const { return _filename; }
osg::observer_ptr<DirectShowImageStream> _imageStream;
};
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,94 @@
/* -*-c++-*- OpenSceneGraph - Copyright (C) 2009 Tharsis Software
*
* This library is open source and may be redistributed and/or modified under
* the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
* (at your option) any later version. The full license is in LICENSE file
* included with this distribution, and on the openscenegraph.org website.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* OpenSceneGraph Public License for more details.
*
* Authors:
* Cedric Pinson <cedric.pinson@plopbyte.net>
*/
#include <osgDB/Registry>
#include <osgDB/FileNameUtils>
#include <osgDB/FileUtils>
#include "DirectShowTexture"
class ReaderWriterDirectShow : public osgDB::ReaderWriter
{
public:
ReaderWriterDirectShow()
{
}
virtual ~ReaderWriterDirectShow()
{
}
virtual const char * className() const
{
return "ReaderWriterDirectShow";
}
virtual ReadResult readImage(const std::string & filename, const osgDB::ReaderWriter::Options * options) const
{
const std::string ext = osgDB::getLowerCaseFileExtension(filename);
if (ext=="directshow") return readImage(osgDB::getNameLessExtension(filename),options);
return readImageStream(filename, options);
}
ReadResult readImageStream(const std::string& filename, const osgDB::ReaderWriter::Options * options) const
{
osg::notify(osg::INFO) << "ReaderWriterFFmpeg::readImage " << filename << std::endl;
const std::string path = osgDB::containsServerAddress(filename) ?
filename :
osgDB::findDataFile(filename, options);
osg::ref_ptr<DirectShowImageStream> image_stream(new DirectShowImageStream);
if (path.empty()) // try with capture
{
std::map<std::string,std::string> map;
if (options)
{
map["captureWantedWidth"] = options->getPluginStringData("captureWantedWidth");
map["captureWantedHeight"] = options->getPluginStringData("captureWantedHeight");
map["captureWantedFps"] = options->getPluginStringData("captureWantedFps");
map["captureVideoDevice"] = options->getPluginStringData("captureVideoDevice");
map["captureSoundDevice"] = options->getPluginStringData("captureSoundDevice");
map["captureSoundDeviceNbChannels"] = options->getPluginStringData("captureSoundDeviceNbChannels");
}
if (filename != "capture")
{
if (!options || (options && options->getPluginStringData("captureVideoDevice").empty()))
map["captureVideoDevice"] = filename;
}
image_stream->setOptions(map);
if (! image_stream->openCaptureDevices())
return ReadResult::FILE_NOT_HANDLED;
return image_stream.release();
}
if (! image_stream->openFile(filename))
return ReadResult::FILE_NOT_HANDLED;
return image_stream.release();
}
private:
};
REGISTER_OSGPLUGIN(directshow, ReaderWriterDirectShow)