2222
2323#include " cinder/Cinder.h"
2424#include " cinder/Capture.h"
25+ #include < iomanip>
2526#if defined( CINDER_MAC ) || defined( CINDER_COCOA_TOUCH_DEVICE )
2627 #import " cinder/CaptureImplAvFoundation.h"
2728 typedef CaptureImplAvFoundation CapturePlatformImpl;
3132#elif defined( CINDER_MSW )
3233 #include " cinder/CaptureImplDirectShow.h"
3334 typedef cinder::CaptureImplDirectShow CapturePlatformImpl;
35+ #elif defined( CINDER_LINUX )
36+ #include " cinder/CaptureImplGStreamer.h"
37+ typedef cinder::CaptureImplGStreamer CapturePlatformImpl;
3438#elif defined( CINDER_ANDROID )
3539 #include " cinder/CaptureImplJni.h"
3640 typedef cinder::CaptureImplJni CapturePlatformImpl;
@@ -42,6 +46,156 @@ using namespace std;
4246
4347namespace cinder {
4448
49+ // ////////////////////////////////////////////////////////////////////////////////////////////////////////////
50+ // Capture::Mode
51+
52+ Capture::Mode::Mode ()
53+ : mSize ( 0 , 0 ), mFrameRate ( MediaTime() ), mCodec ( Codec::Unknown ), mPixelFormat ( PixelFormat::Unknown )
54+ {
55+ }
56+
57+ Capture::Mode::Mode ( int32_t width, int32_t height, const MediaTime& frameRate, Codec codec, PixelFormat pixelFormat, const std::string& description )
58+ : mSize ( width, height ), mFrameRate ( frameRate ), mCodec ( codec ), mPixelFormat ( pixelFormat ), mDescription ( description )
59+ {
60+ }
61+
62+ bool Capture::Mode::isRGBFormat () const
63+ {
64+ switch ( mPixelFormat ) {
65+ case PixelFormat::RGB24:
66+ case PixelFormat::BGR24:
67+ case PixelFormat::ARGB32:
68+ case PixelFormat::BGRA32:
69+ return true ;
70+ default :
71+ return false ;
72+ }
73+ }
74+
75+ bool Capture::Mode::isYUVFormat () const
76+ {
77+ switch ( mPixelFormat ) {
78+ case PixelFormat::YUV420P:
79+ case PixelFormat::NV12:
80+ case PixelFormat::YUY2:
81+ case PixelFormat::UYVY:
82+ case PixelFormat::I420:
83+ case PixelFormat::YV12:
84+ return true ;
85+ default :
86+ return false ;
87+ }
88+ }
89+
90+ std::string Capture::Mode::getCodecString () const
91+ {
92+ switch ( mCodec ) {
93+ case Codec::Uncompressed: return " Uncompressed" ;
94+ case Codec::JPEG: return " JPEG" ;
95+ case Codec::H264: return " H264" ;
96+ case Codec::HEVC: return " HEVC" ;
97+ case Codec::Unknown: return " Unknown" ;
98+ default : return " Unknown" ;
99+ }
100+ }
101+
102+ std::string Capture::Mode::getPixelFormatString () const
103+ {
104+ switch ( mPixelFormat ) {
105+ case PixelFormat::RGB24: return " RGB24" ;
106+ case PixelFormat::BGR24: return " BGR24" ;
107+ case PixelFormat::ARGB32: return " ARGB32" ;
108+ case PixelFormat::BGRA32: return " BGRA32" ;
109+ case PixelFormat::YUV420P: return " YUV420P" ;
110+ case PixelFormat::NV12: return " NV12" ;
111+ case PixelFormat::YUY2: return " YUY2" ;
112+ case PixelFormat::UYVY: return " UYVY" ;
113+ case PixelFormat::I420: return " I420" ;
114+ case PixelFormat::YV12: return " YV12" ;
115+ case PixelFormat::Unknown: return " Unknown" ;
116+ default : return " Unknown" ;
117+ }
118+ }
119+
120+ bool Capture::Mode::operator ==( const Mode& other ) const
121+ {
122+ return mSize == other.mSize &&
123+ mFrameRate == other.mFrameRate &&
124+ mCodec == other.mCodec &&
125+ mPixelFormat == other.mPixelFormat ;
126+ }
127+
128+ bool Capture::Mode::operator <( const Mode& other ) const
129+ {
130+ // Sort by resolution (pixel count), then frame rate, then codec, then pixel format
131+ int32_t thisPixels = getPixelCount ();
132+ int32_t otherPixels = other.getPixelCount ();
133+
134+ if ( thisPixels != otherPixels )
135+ return thisPixels < otherPixels;
136+
137+ if ( mFrameRate != other.mFrameRate )
138+ return mFrameRate < other.mFrameRate ;
139+
140+ if ( mCodec != other.mCodec )
141+ return static_cast <int >( mCodec ) < static_cast <int >( other.mCodec );
142+
143+ return static_cast <int >( mPixelFormat ) < static_cast <int >( other.mPixelFormat );
144+ }
145+
146+ // Stream operators
147+ std::ostream& operator <<( std::ostream& os, const Capture::Mode& mode )
148+ {
149+ // Format FPS to 2 decimal places
150+ os << mode.getWidth () << " x" << mode.getHeight ()
151+ << " @" ;
152+
153+ // Use fixed format with 2 decimal precision for FPS
154+ std::ios_base::fmtflags oldFlags = os.flags ();
155+ std::streamsize oldPrecision = os.precision ();
156+ os << std::fixed << std::setprecision (2 ) << mode.getFrameRateFloat ();
157+ os.flags (oldFlags);
158+ os.precision (oldPrecision);
159+
160+ os << " fps"
161+ << " " << mode.getCodecString ()
162+ << " " << mode.getPixelFormatString ();
163+ return os;
164+ }
165+
166+ std::ostream& operator <<( std::ostream& os, const Capture::Mode::Codec& codec )
167+ {
168+ switch ( codec ) {
169+ case Capture::Mode::Codec::Uncompressed: return os << " Uncompressed" ;
170+ case Capture::Mode::Codec::JPEG: return os << " JPEG" ;
171+ case Capture::Mode::Codec::H264: return os << " H264" ;
172+ case Capture::Mode::Codec::HEVC: return os << " HEVC" ;
173+ case Capture::Mode::Codec::Unknown: return os << " Unknown" ;
174+ default : return os << " Unknown" ;
175+ }
176+ }
177+
178+ std::ostream& operator <<( std::ostream& os, const Capture::Mode::PixelFormat& format )
179+ {
180+ switch ( format ) {
181+ case Capture::Mode::PixelFormat::RGB24: return os << " RGB24" ;
182+ case Capture::Mode::PixelFormat::BGR24: return os << " BGR24" ;
183+ case Capture::Mode::PixelFormat::ARGB32: return os << " ARGB32" ;
184+ case Capture::Mode::PixelFormat::BGRA32: return os << " BGRA32" ;
185+ case Capture::Mode::PixelFormat::YUV420P: return os << " YUV420P" ;
186+ case Capture::Mode::PixelFormat::NV12: return os << " NV12" ;
187+ case Capture::Mode::PixelFormat::YUY2: return os << " YUY2" ;
188+ case Capture::Mode::PixelFormat::UYVY: return os << " UYVY" ;
189+ case Capture::Mode::PixelFormat::I420: return os << " I420" ;
190+ case Capture::Mode::PixelFormat::YV12: return os << " YV12" ;
191+ case Capture::Mode::PixelFormat::Unknown: return os << " Unknown" ;
192+ default : return os << " Unknown" ;
193+ }
194+ }
195+
196+ // ////////////////////////////////////////////////////////////////////////////////////////////////////////////
197+ // Capture
198+
45199const vector<Capture::DeviceRef>& Capture::getDevices ( bool forceRefresh )
46200{
47201#if defined( CINDER_COCOA )
@@ -71,7 +225,7 @@ Capture::DeviceRef Capture::findDeviceByNameContains( const string &nameFragment
71225 return DeviceRef ();
72226}
73227
74- Capture::Capture ( int32_t width, int32_t height, const DeviceRef device )
228+ Capture::Capture ( int32_t width, int32_t height, const DeviceRef device )
75229{
76230#if defined( CINDER_COCOA )
77231 mImpl = [[::CapturePlatformImpl alloc] initWithDevice:device width:width height:height];
@@ -80,6 +234,15 @@ Capture::Capture( int32_t width, int32_t height, const DeviceRef device )
80234#endif
81235}
82236
237+ Capture::Capture ( const DeviceRef& device, const Mode& mode )
238+ {
239+ #if defined( CINDER_COCOA )
240+ mImpl = [[::CapturePlatformImpl alloc] initWithDevice:device mode:mode];
241+ #else
242+ mImpl = new CapturePlatformImpl ( device, mode );
243+ #endif
244+ }
245+
83246Capture::~Capture ()
84247{
85248#if defined( CINDER_COCOA )
0 commit comments