Permalink
Browse files

Tidy up a few more video input features. Fix static swscaler bug. All…

…ow child displays to be retrieved by index.

Signed-off-by: Steven Lovegrove <stevenlovegrove@gmail.com>
  • Loading branch information...
stevenlovegrove committed Apr 6, 2012
1 parent b0c70b4 commit 5927f4a361b1b282418171daaa839265a7107b56
View
@@ -1,10 +1,15 @@
== What is Pangolin ==
-Pangolin is a Lightweight collection of utilities for rapid vision prototyping.
-At its heart is a simple OpenGl display library which can help manage viewports
-and offers an advanced but intuitive 3D navigation handler. Pangolin also
-provides a mechanism for manipulating program variables through config files and
-ui integration, and offers a simple mechanism for lightweight video input.
+Pangolin is a lightweight rapid development library for managing OpenGL
+display / interaction and video input. At its heart is a simple OpenGl
+viewport manager which can help to modularise 3D visualisation without
+adding to its complexity, and offers an advanced but intuitive 3D
+navigation handler. Pangolin also provides a mechanism for manipulating
+program variables through config files and ui integration.
+
+The ethos of Pangolin is to reduce the boilerplate code that normally
+gets written to visualise and interact with (typically image and 3D
+based) systems, without compromising performance.
== Required Dependencies ==
@@ -24,7 +24,7 @@ std::istream& operator>> (std::istream& is, CustomType& o){
}
int main( int /*argc*/, char* argv[] )
-{
+{
// Load configuration data
pangolin::ParseVarsFile("app.cfg");
@@ -41,15 +41,17 @@ int main( int /*argc*/, char* argv[] )
s_cam.Set(ProjectionMatrix(640,480,420,420,320,240,0.1,1000));
s_cam.Set(IdentityMatrix(GlModelViewStack));
+ const int UI_WIDTH = 180;
+
// Add named OpenGL viewport to window and provide 3D Handler
View& d_cam = pangolin::Display("cam")
- .SetBounds(0.0, 1.0, Attach::Pix(200), 1.0, -640.0f/480.0f)
+ .SetBounds(0.0, 1.0, Attach::Pix(UI_WIDTH), 1.0, -640.0f/480.0f)
.SetHandler(new Handler3D(s_cam));
// Add named Panel and bind to variables beginning 'ui'
// A Panel is just a View with a default layout and input handling
View& d_panel = pangolin::CreatePanel("ui")
- .SetBounds(0.0, 1.0, 0.0, Attach::Pix(200));
+ .SetBounds(0.0, 1.0, 0.0, Attach::Pix(UI_WIDTH));
// Default hooks for exiting (Esc) and fullscreen (tab).
while( !pangolin::ShouldQuit() )
@@ -19,11 +19,13 @@ int main( int /*argc*/, char* argv[] )
DataLog log;
+ const int UI_WIDTH = 180;
+
View& d_graph = pangolin::CreatePlotter("x",&log)
- .SetBounds(0.0, 1.0, Attach::Pix(200), 1.0);
+ .SetBounds(0.0, 1.0, Attach::Pix(UI_WIDTH), 1.0);
View& d_panel = pangolin::CreatePanel("ui")
- .SetBounds(0.0, 1.0, 0.0, Attach::Pix(200) );
+ .SetBounds(0.0, 1.0, 0.0, Attach::Pix(UI_WIDTH) );
double t = 0;
@@ -48,15 +48,17 @@ int main( int /*argc*/, char* argv[] )
s_cam.Set(ProjectionMatrix(640,480,420,420,320,240,0.1,1000));
s_cam.Set(IdentityMatrix(GlModelViewStack));
+ const int UI_WIDTH = 180;
+
// Add named OpenGL viewport to window and provide 3D Handler
View& d_cam = pangolin::Display("cam")
- .SetBounds(0.0, 1.0, Attach::Pix(150), 1.0, -640.0f/480.0f)
+ .SetBounds(0.0, 1.0, Attach::Pix(UI_WIDTH), 1.0, -640.0f/480.0f)
.SetHandler(new Handler3D(s_cam));
// Add named Panel and bind to variables beginning 'ui'
// A Panel is just a View with a default layout and input handling
View& d_panel = pangolin::CreatePanel("ui")
- .SetBounds(0.0, 1.0, 0.0, Attach::Pix(150));
+ .SetBounds(0.0, 1.0, 0.0, Attach::Pix(UI_WIDTH));
#ifdef USE_CUTIL
// Apply timer as used by CUDA samples
View
@@ -125,6 +125,14 @@ namespace pangolin
return context->base;
}
+ View& CreateDisplay()
+ {
+ int iguid = rand();
+ std::stringstream ssguid;
+ ssguid << iguid;
+ return Display(ssguid.str());
+ }
+
View& Display(const std::string& name)
{
// Get / Create View
@@ -637,6 +645,10 @@ namespace pangolin
return *this;
}
+ View& View::operator[](int i)
+ {
+ return *views[i];
+ }
View& View::SetHandler(Handler* h)
{
View
@@ -289,6 +289,9 @@ namespace pangolin
View& SetLayout(Layout layout);
View& AddDisplay(View& view);
+ //! Return (i)th child of this view
+ View& operator[](int i);
+
// Desired width / height aspect (0 if dynamic)
double aspect;
@@ -365,9 +368,15 @@ namespace pangolin
GLdouble rot_center[3];
};
+ //! Retrieve 'base' display, corresponding to entire window
View& DisplayBase();
+
+ //! Create or retrieve named display
View& Display(const std::string& name);
+ //! Create unnamed display
+ View& CreateDisplay();
+
OpenGlMatrixSpec ProjectionMatrixRUB_BottomLeft(int w, int h, double fu, double fv, double u0, double v0, double zNear, double zFar );
OpenGlMatrixSpec ProjectionMatrixRDF_TopLeft(int w, int h, double fu, double fv, double u0, double v0, double zNear, double zFar );
OpenGlMatrixSpec ProjectionMatrixRDF_BottomLeft(int w, int h, double fu, double fv, double u0, double v0, double zNear, double zFar );
View
@@ -35,7 +35,10 @@ namespace pangolin
PixelFormat FfmpegFmtFromString(const std::string fmt)
{
std::string lfmt = boost::algorithm::to_lower_copy(fmt);
- return av_get_pix_fmt(lfmt.c_str());
+ if(!lfmt.compare("gray8") || !lfmt.compare("grey8") || !lfmt.compare("grey")) {
+ return PIX_FMT_GRAY8;
+ }
+ return av_get_pix_fmt(lfmt.c_str());
}
#define TEST_PIX_FMT_RETURN(fmt) case PIX_FMT_##fmt: return #fmt;
@@ -118,13 +121,13 @@ std::string FfmpegFmtToString(const PixelFormat fmt)
#undef TEST_PIX_FMT_RETURN
-FfmpegVideo::FfmpegVideo(const std::string filename, const std::string strfmtout, const std::string codec_hint)
+FfmpegVideo::FfmpegVideo(const std::string filename, const std::string strfmtout, const std::string codec_hint, bool dump_info)
:pFormatCtx(0)
{
- InitUrl(filename, strfmtout, codec_hint);
+ InitUrl(filename, strfmtout, codec_hint, dump_info);
}
-void FfmpegVideo::InitUrl(const std::string url, const std::string strfmtout, const std::string codec_hint)
+void FfmpegVideo::InitUrl(const std::string url, const std::string strfmtout, const std::string codec_hint, bool dump_info)
{
if( url.find('*') != url.npos )
throw VideoException("Wildcards not supported. Please use ffmpegs printf style formatting for image sequences. e.g. img-000000%04d.ppm");
@@ -153,13 +156,15 @@ void FfmpegVideo::InitUrl(const std::string url, const std::string strfmtout, co
if(av_find_stream_info(pFormatCtx)<0)
throw VideoException("Couldn't find stream information");
- // Dump information about file onto standard error
+ if(dump_info) {
+ // Dump information about file onto standard error
#ifdef CODEC_TYPE_VIDEO
- // Old (deprecated) interface
- dump_format(pFormatCtx, 0, url.c_str(), false);
+ // Old (deprecated) interface
+ dump_format(pFormatCtx, 0, url.c_str(), false);
#else
- av_dump_format(pFormatCtx, 0, url.c_str(), false);
+ av_dump_format(pFormatCtx, 0, url.c_str(), false);
#endif
+ }
// Find the first video stream
videoStream=-1;
@@ -203,17 +208,32 @@ void FfmpegVideo::InitUrl(const std::string url, const std::string strfmtout, co
// Allocate an AVFrame structure
pFrameOut=avcodec_alloc_frame();
if(pFrameOut==0)
- throw VideoException("Couldn't allocate frame");
+ throw VideoException("Couldn't allocate frame");
fmtout = FfmpegFmtFromString(strfmtout);
+ if(fmtout == PIX_FMT_NONE )
+ throw VideoException("Output format not recognised",strfmtout);
+
+ // Image dimensions
+ const int w = pVidCodecCtx->width;
+ const int h = pVidCodecCtx->height;
// Determine required buffer size and allocate buffer
- numBytesOut=avpicture_get_size(fmtout, pVidCodecCtx->width, pVidCodecCtx->height);
+ numBytesOut=avpicture_get_size(fmtout, w, h);
buffer= new uint8_t[numBytesOut];
// Assign appropriate parts of buffer to image planes in pFrameRGB
- avpicture_fill((AVPicture *)pFrameOut, buffer, fmtout, pVidCodecCtx->width, pVidCodecCtx->height);
+ avpicture_fill((AVPicture *)pFrameOut, buffer, fmtout, w, h);
+
+ // Allocate SWS for converting pixel formats
+ img_convert_ctx = sws_getContext(w, h,
+ pVidCodecCtx->pix_fmt,
+ w, h, fmtout, FFMPEG_POINT,
+ NULL, NULL, NULL);
+ if(img_convert_ctx == NULL) {
+ throw VideoException("Cannot initialize the conversion context");
+ }
}
FfmpegVideo::~FfmpegVideo()
@@ -230,6 +250,9 @@ FfmpegVideo::~FfmpegVideo()
// Close the video file
av_close_input_file(pFormatCtx);
+
+ // Free pixel conversion context
+ sws_freeContext(img_convert_ctx);
}
@@ -275,25 +298,8 @@ bool FfmpegVideo::GrabNext(unsigned char* image, bool /*wait*/)
}
// Did we get a video frame?
- if(gotFrame)
- {
- static struct SwsContext *img_convert_ctx;
-
- if(img_convert_ctx == NULL) {
- const int w = pVidCodecCtx->width;
- const int h = pVidCodecCtx->height;
-
- img_convert_ctx = sws_getContext(w, h,
- pVidCodecCtx->pix_fmt,
- w, h, fmtout, FFMPEG_POINT,
- NULL, NULL, NULL);
- if(img_convert_ctx == NULL) {
- fprintf(stderr, "Cannot initialize the conversion context!\n");
- exit(1);
- }
- }
- sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, pVidCodecCtx->height, pFrameOut->data, pFrameOut->linesize);
-
+ if(gotFrame) {
+ sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, pVidCodecCtx->height, pFrameOut->data, pFrameOut->linesize);
memcpy(image,pFrameOut->data[0],numBytesOut);
}
View
@@ -53,7 +53,7 @@ namespace pangolin
class FfmpegVideo : public VideoInterface
{
public:
- FfmpegVideo(const std::string filename, const std::string fmtout = "RGB24", const std::string codec_hint = "");
+ FfmpegVideo(const std::string filename, const std::string fmtout = "RGB24", const std::string codec_hint = "", bool dump_info = false);
~FfmpegVideo();
//! Implement VideoSource::Start()
@@ -75,8 +75,9 @@ class FfmpegVideo : public VideoInterface
bool GrabNewest( unsigned char* image, bool wait = true );
protected:
- void InitUrl(const std::string filename, const std::string fmtout = "RGB24", const std::string codec_hint = "" );
+ void InitUrl(const std::string filename, const std::string fmtout = "RGB24", const std::string codec_hint = "", bool dump_info = false );
+ SwsContext *img_convert_ctx;
AVFormatContext *pFormatCtx;
int videoStream;
int audioStream;
View
@@ -54,6 +54,8 @@ struct GlTexture
void Bind() const;
void Unbind() const;
+ //! data_layout normally one of GL_LUMINANCE, GL_RGB, ...
+ //! data_type normally one of GL_UNSIGNED_BYTE, GL_FLOAT
void Upload(void* image, GLenum data_layout = GL_LUMINANCE, GLenum data_type = GL_FLOAT);
void SetLinear();
View
@@ -47,6 +47,7 @@ namespace pangolin
const VideoPixelFormat SupportedVideoPixelFormats[] =
{
+ {"GRAY8", 1, {8}, 8, false},
{"RGB24", 3, {8,8,8}, 24, false},
{"BGR24", 3, {8,8,8}, 24, false},
{"YUYV422", 3, {4,2,2}, 16, false},

0 comments on commit 5927f4a

Please sign in to comment.