AvTranscoder  0.9.4
C++APIforLibav/FFmpeg
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Window.cpp
Go to the documentation of this file.
1 #include "Window.hpp"
2 
3 #ifdef __APPLE__
4 #include <OpenGL/gl.h>
5 #include <GLUT/glut.h>
6 #else
7 #include <GL/gl.h>
8 #include <GL/glut.h>
9 #include <GL/freeglut.h>
10 #endif
11 
12 #include <iostream>
13 #include <iomanip>
14 #include <cstring>
15 
17 
18 size_t Window::_width = 0;
19 size_t Window::_height = 0;
20 
21 int Window::_x1 = -1.0;
22 int Window::_x2 = 1.0;
23 int Window::_y1 = 1.0;
24 int Window::_y2 = -1.0;
25 
26 int Window::_xMinViewport = 0;
27 int Window::_yMinViewport = 0;
28 int Window::_xMouseRef = 0;
29 int Window::_yMouseRef = 0;
30 
31 int Window::_windowId = 0;
32 
33 float Window::_currentZoom = 1.0;
34 float Window::_factorZoom = 1.25;
35 
36 float Window::_scale = 1.0;
37 
38 bool Window::_play = false;
39 
40 bool Window::_flip = false;
41 bool Window::_flop = false;
42 
43 // channel properties
44 bool Window::_showRedChannel = false;
45 bool Window::_showGreenChannel = false;
46 bool Window::_showBlueChannel = false;
47 bool Window::_showAlphaChannel = false;
48 
49 // image properties
51 {
52  const char* data;
54  size_t width;
55  size_t height;
56  GLenum format;
57  GLenum type;
58  size_t component;
59 };
60 
62 
63 void loadNewTexture(const ImgProperties& properties)
64 {
65  // loading texture
66  glTexImage2D(GL_TEXTURE_2D, 0, properties.internalFormat, properties.width, properties.height, 0, properties.format,
67  properties.type, properties.data);
68  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
69  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
70 
71  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
72  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
73 
74  glEnable(GL_TEXTURE_2D);
75 }
76 
77 void loadNewTexture(const char* data, GLint internalFormat, size_t width, size_t height, GLenum format, GLenum type)
78 {
79  _imageProperties.data = data;
80  _imageProperties.internalFormat = internalFormat;
81  _imageProperties.width = width;
82  _imageProperties.height = height;
83  _imageProperties.format = format;
84  _imageProperties.type = type;
85 
86  switch(_imageProperties.format)
87  {
88  case GL_LUMINANCE:
89  _imageProperties.component = 1;
90  break;
91  case GL_RGB:
92  _imageProperties.component = 3;
93  break;
94  case GL_RGBA:
95  _imageProperties.component = 4;
96  break;
97  }
98 
99  loadNewTexture(_imageProperties);
100 }
101 
103 {
104  _reader = &reader;
107 
108  char* argv[2] = {(char*)"", NULL};
109  int argc = 1;
110  glutInit(&argc, argv);
111  glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_RGBA | GLUT_MULTISAMPLE);
112  glutInitWindowSize(_width, _height);
113  glutInitWindowPosition(0, 0);
114 #ifdef GLUT_ACTION_ON_WINDOW_CLOSE
115  glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_CONTINUE_EXECUTION);
116 #endif
117 
118  _windowId = glutCreateWindow("AV Player Viewer");
119  glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
120  glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
121 
122  glutDisplayFunc(display);
123  glutKeyboardFunc(keyboard);
124  glutSpecialFunc(specialKeyboard);
125  glutMouseFunc(mouse);
126  glutMotionFunc(motion);
127  glutReshapeFunc(reshape);
128 }
129 
131 {
133  glutMainLoop();
134 }
135 
137 {
138  if(glutGetWindow() == 0)
139  return;
140  glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
141  glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
142 
143  glBegin(GL_QUADS);
144 
145  float x1 = _x1;
146  float x2 = _x2;
147 
148  float y1 = _y1;
149  float y2 = _y2;
150 
151  if(_flip)
152  {
153  y1 = -y1;
154  y2 = -y2;
155  }
156  if(_flop)
157  {
158  x1 = -x1;
159  x2 = -x2;
160  }
161 
162  glTexCoord2f(0, 0);
163  glVertex2f(x1, y1);
164 
165  glTexCoord2f(0, 1);
166  glVertex2f(x1, y2);
167 
168  glTexCoord2f(1, 1);
169  glVertex2f(x2, y2);
170 
171  glTexCoord2f(1, 0);
172  glVertex2f(x2, y1);
173 
174  glEnd();
175 
176  glutSwapBuffers();
177 }
178 
179 void Window::keyboard(unsigned char k, int x, int y)
180 {
181  bool shift = false;
182  if(glutGetModifiers() == GLUT_ACTIVE_SHIFT)
183  {
184  shift = true;
185  }
186 
187  switch(k)
188  {
189  case '\r':
190  glutDestroyWindow(_windowId);
191  _windowId = 0;
192  break;
193  case 27: // ESCAPE key
194  glutDestroyWindow(_windowId);
195  _windowId = 0;
196  break;
197  case 'i':
199  break;
200  case 'z':
201  glutReshapeWindow(_width, _height);
202  _currentZoom = 1.0;
203  _x1 = -1.0;
204  _x2 = 1.0;
205  _y1 = 1.0;
206  _y2 = -1.0;
207  glutPostRedisplay();
208  break;
209  case 'h':
210  displayHelp();
211  break;
212  case 32: // spacebar
213  _play = !_play;
214  loopPlaying(0);
215  break;
216 
217  case 'r':
219  break;
220  case 'g':
222  break;
223  case 'b':
225  break;
226  case 'a':
228  break;
229  case 'H':
230  if(shift)
231  {
232  _flop = !_flop;
233  glutPostRedisplay();
234  }
235  break;
236  case 'V':
237  if(shift)
238  {
239  _flip = !_flip;
240  glutPostRedisplay();
241  }
242  break;
243  }
244 }
245 
246 void Window::specialKeyboard(int k, int x, int y)
247 {
248  // std::cout << "k=" << k << " x=" << x << " y=" << y << std::endl;
249  switch(k)
250  {
251  case GLUT_KEY_UP:
252  // cursor move
253  break;
254  case GLUT_KEY_DOWN:
255  // cursor move
256  break;
257  case GLUT_KEY_LEFT:
258  // cursor move
260  break;
261  case GLUT_KEY_RIGHT:
262  // cursor move
264  break;
265  case GLUT_KEY_HOME:
267  case GLUT_KEY_END:
268  break;
269  case GLUT_KEY_F1:
270  displayHelp();
271  break;
272  }
273 }
274 
275 void Window::mouse(int button, int state, int x, int y)
276 {
277  if(state == 0 && button == 0)
278  {
279  int iX, iY;
280 
281  mapToImage(x, y, iX, iY);
282 
283  if(iX < 0 || iY < 0 || iX >= (int)_imageProperties.width || iY >= (int)_imageProperties.height)
284  return;
285 
286  std::cout << "at " << std::setw(4) << iX << "," << std::setw(4) << (int)_imageProperties.height - iY << ": ";
287 
288  for(size_t i = 0; i < _imageProperties.component; i++)
289  {
290  size_t idx = (iX + iY * _imageProperties.width) * _imageProperties.component + i;
291  switch(_imageProperties.type)
292  {
293  case GL_UNSIGNED_BYTE:
294  {
295  const unsigned char* d = (const unsigned char*)_imageProperties.data;
296  std::cout << std::setw(5) << (unsigned int)d[idx];
297  break;
298  }
299  case GL_UNSIGNED_SHORT:
300  {
301  const unsigned short* d = (const unsigned short*)_imageProperties.data;
302  std::cout << std::setw(7) << d[idx];
303  break;
304  }
305  case GL_FLOAT:
306  {
307  const float* d = (const float*)_imageProperties.data;
308  std::cout << std::setw(10) << d[idx];
309  break;
310  }
311  }
312  }
313  std::cout << std::endl;
314  }
315  if(state == 0 && (button == 3 || button == 4))
316  {
317  int iX, iY, iX2, iY2;
318 
319  mapToImage(x, y, iX, iY);
320 
321  if(button == 3)
322  {
324  zoom(_factorZoom);
325  }
326  else
327  {
329  zoom(1.0 / _factorZoom);
330  }
331 
332  mapToImage(x, y, iX2, iY2);
333 
334  move((_currentZoom / _imageProperties.width * 2) * (iX2 - iX),
335  (_currentZoom / _imageProperties.height * 2) * (iY2 - iY));
336 
337  glutPostRedisplay();
338  }
339 
340  _xMouseRef = x;
341  _yMouseRef = y;
342 }
343 
344 void Window::motion(int x, int y)
345 {
346  float x_diff, y_diff;
347 
348  x_diff = (x - _xMouseRef) / _currentZoom;
349  y_diff = (_yMouseRef - y) / _currentZoom;
350 
351  if(_flip)
352  {
353  y_diff *= -1.0;
354  }
355 
356  if(_flop)
357  {
358  x_diff *= -1.0;
359  }
360 
361  move(_currentZoom / _imageProperties.width * 2 * x_diff, _currentZoom / _imageProperties.height * 2 * y_diff);
362 
363  _xMouseRef = x;
364  _yMouseRef = y;
365 
366  glutPostRedisplay();
367 }
368 
369 void Window::reshape(int width, int height)
370 {
371  float w, h, xPos, yPos;
372 
373  if((float)_width / _height > (float)width / height)
374  {
375  w = width;
376  h = 1.0f * _height / _width * (float)width;
377  xPos = 0.0;
378  yPos = 0.5f * (height - h);
379  }
380  else
381  {
382  w = 1.0f * _width / _height * (float)height;
383  h = height;
384  xPos = 0.5f * (width - w);
385  yPos = 0.0;
386  }
387 
388  _xMinViewport = xPos;
389  _yMinViewport = yPos;
390 
391  _scale = w / _width;
392 
393  glViewport((GLsizei)xPos, (GLsizei)yPos, (GLsizei)w, (GLsizei)h);
394  glutReshapeWindow(width, height);
395 }
396 
398 {
399  static const std::string kViewerHelp =
400  "Av Player Viewer Help\n"
401  "i : information about image (dimensions, bit depth, channels) + video stream\n"
402  "z : zoom view to 1:1\n"
403  "h, F1 : print help\n"
404  "SHIFT + V : flip\n"
405  "SHIFT + H : flop\n"
406  "clic on image : print RGBA values\n"
407  "ESC, Return, Space : quit and continue process";
408  std::cout << kViewerHelp << std::endl;
409 }
410 
412 {
413  std::string textureType;
414  switch(_imageProperties.format)
415  {
416  case GL_LUMINANCE:
417  textureType = "Gray ";
418  break;
419  case GL_RGB:
420  textureType = "RGB ";
421  break;
422  case GL_RGBA:
423  textureType = "RGBA ";
424  break;
425  }
426  switch(_imageProperties.type)
427  {
428  case GL_UNSIGNED_BYTE:
429  textureType += "8 bits";
430  break;
431  case GL_UNSIGNED_SHORT:
432  textureType += "16 bits";
433  break;
434  case GL_FLOAT:
435  textureType += "32 float";
436  break;
437  }
438  std::cout << textureType << " " << _width << "x" << _height << std::endl;
439 
440  // stream info
442  if(properties != NULL)
443  std::cout << *properties << std::endl;
444 }
445 
446 void Window::move(float x, float y)
447 {
448  _x1 += x;
449  _x2 += x;
450  _y1 += y;
451  _y2 += y;
452 }
453 
454 void Window::zoom(float factor)
455 {
456  _x1 *= factor;
457  _x2 *= factor;
458  _y1 *= factor;
459  _y2 *= factor;
460 }
461 
462 void Window::mapToImage(int x, int y, int& iX, int& iY)
463 {
464  int mapX, mapY;
465  float mx, my;
466 
467  mapX = (x - _xMinViewport) / _scale;
468  mapY = (y - _yMinViewport) / _scale;
469 
470  if(!_flip)
471  {
472  mapY = _imageProperties.height - mapY;
473  }
474 
475  if(_flop)
476  {
477  mapX = _imageProperties.width - mapX;
478  }
479 
480  mx = (float)mapX / (float)_imageProperties.width * 2.0 - 1.0;
481  iX = ((_x1 - mx) / (_currentZoom * 2.0) * (float)_imageProperties.width * -1.0) + 0.5;
482 
483  my = (float)mapY / (float)_imageProperties.height * 2.0 - 1.0;
484  iY = ((_y1 - my) / (_currentZoom * 2.0) * (float)_imageProperties.height * -1.0) + 0.5;
485 }
486 
487 void Window::setTransfert(float red, float green, float blue, float alpha)
488 {
489  switch(_imageProperties.format)
490  {
491  case GL_LUMINANCE:
492  return;
493  case GL_RGB:
494  glPixelTransferf(GL_RED_SCALE, red);
495  glPixelTransferf(GL_GREEN_SCALE, green);
496  glPixelTransferf(GL_BLUE_SCALE, blue);
497  break;
498  case GL_RGBA:
499  glPixelTransferf(GL_RED_SCALE, red);
500  glPixelTransferf(GL_GREEN_SCALE, green);
501  glPixelTransferf(GL_BLUE_SCALE, blue);
502  glPixelTransferf(GL_ALPHA_SCALE, alpha);
503  break;
504  }
505 }
506 
507 void Window::displayChannelTexture(bool& channel, const float red, const float green, const float blue)
508 {
510  if(!channel)
511  {
512  setTransfert(red, green, blue);
513  _showRedChannel = false;
514  _showGreenChannel = false;
515  _showBlueChannel = false;
516  _showAlphaChannel = false;
517  channel = true;
518  }
519  else
520  {
521  setTransfert(1.f, 1.f, 1.f);
522  channel = false;
523  }
524  loadNewTexture(p);
525 
526  glutPostRedisplay();
527 }
528 
530 {
531  displayChannelTexture(_showRedChannel, 1.f, 0.f, 0.f);
532 }
533 
535 {
537 }
538 
540 {
541  displayChannelTexture(_showBlueChannel, 0.f, 0.f, 1.f);
542 }
543 
545 {
546  glutPostRedisplay();
547 }
548 
550 {
551  const char* buffer = (const char*)_reader->readNextFrame()->getData()[0];
553  GL_UNSIGNED_BYTE);
554  display();
555 }
556 
558 {
559  const char* buffer = (const char*)_reader->readPrevFrame()->getData()[0];
561  GL_UNSIGNED_BYTE);
562  display();
563 }
564 
566 {
567  displayAtFrame(0);
568 }
569 
570 void Window::displayAtFrame(const size_t frame)
571 {
572  const char* buffer = (const char*)_reader->readFrameAt(frame)->getData()[0];
574  GL_UNSIGNED_BYTE);
575  display();
576 }
577 
578 void Window::loopPlaying(int value)
579 {
580  if(_play)
581  glutTimerFunc(40, &loopPlaying, 0);
583 }
static float _scale
Definition: Window.hpp:67
static void displayFirstFrame()
Definition: Window.cpp:565
static int _windowId
Definition: Window.hpp:61
static int _x1
Definition: Window.hpp:50
void launch()
Definition: Window.cpp:130
static bool _flop
Definition: Window.hpp:72
ImgProperties _imageProperties
Definition: Window.cpp:61
static int _x2
Definition: Window.hpp:51
static float _currentZoom
Definition: Window.hpp:64
static bool _showBlueChannel
Definition: Window.hpp:76
static int _xMinViewport
Definition: Window.hpp:55
const char * data
Definition: Window.cpp:52
static void specialKeyboard(int k, int x, int y)
Definition: Window.cpp:246
static size_t _width
Definition: Window.hpp:47
static bool _showAlphaChannel
Definition: Window.hpp:77
static void displayInformations()
Definition: Window.cpp:411
static void motion(int x, int y)
Definition: Window.cpp:344
Window(avtranscoder::VideoReader &reader)
Definition: Window.cpp:102
static void displayChannelTexture(bool &channel, const float red, const float green, const float blue)
Definition: Window.cpp:507
static avtranscoder::VideoReader * _reader
Definition: Window.hpp:45
static bool _play
Definition: Window.hpp:69
static void mouse(int button, int state, int x, int y)
Definition: Window.cpp:275
size_t height
Definition: Window.cpp:55
static void loopPlaying(int value)
Definition: Window.cpp:578
static int _y2
Definition: Window.hpp:53
size_t getOutputHeight() const
Definition: VideoReader.hpp:34
static void mapToImage(int x, int y, int &iX, int &iY)
Definition: Window.cpp:462
static int _xMouseRef
Definition: Window.hpp:58
static float _factorZoom
Definition: Window.hpp:65
static void reshape(int width, int height)
Definition: Window.cpp:369
unsigned char ** getData()
Get all the data of the frame.
Definition: Frame.hpp:35
static void showAlphaChannelTexture()
Definition: Window.cpp:544
static int _y1
Definition: Window.hpp:52
static void displayPrevFrame()
Definition: Window.cpp:557
static void setTransfert(float red, float green, float blue, float alpha=1.f)
Definition: Window.cpp:487
GLenum type
Definition: Window.cpp:57
size_t width
Definition: Window.cpp:54
Frame * readPrevFrame()
Definition: IReader.cpp:54
static bool _showRedChannel
Definition: Window.hpp:74
const VideoProperties * getSourceVideoProperties() const
Definition: VideoReader.hpp:41
static void display()
Definition: Window.cpp:136
static bool _showGreenChannel
Definition: Window.hpp:75
Frame * readFrameAt(const size_t frame)
Definition: IReader.cpp:59
static int _yMinViewport
Definition: Window.hpp:56
static void displayHelp()
Definition: Window.cpp:397
static void showRedChannelTexture()
Definition: Window.cpp:529
Frame * readNextFrame()
Definition: IReader.cpp:49
static void move(float x, float y)
Definition: Window.cpp:446
void loadNewTexture(const ImgProperties &properties)
Definition: Window.cpp:63
static void keyboard(unsigned char k, int x, int y)
Definition: Window.cpp:179
GLenum format
Definition: Window.cpp:56
static void displayAtFrame(const size_t frame)
Definition: Window.cpp:570
static void showBlueChannelTexture()
Definition: Window.cpp:539
size_t getOutputNbComponents() const
Definition: VideoReader.hpp:35
static int _yMouseRef
Definition: Window.hpp:59
GLint internalFormat
Definition: Window.cpp:53
static bool _flip
Definition: Window.hpp:71
static size_t _height
Definition: Window.hpp:48
static void showGreenChannelTexture()
Definition: Window.cpp:534
static void zoom(float factor)
Definition: Window.cpp:454
size_t component
Definition: Window.cpp:58
static void displayNextFrame()
Definition: Window.cpp:549
size_t getOutputWidth() const
Definition: VideoReader.hpp:33