GLVideoView::GLVideoView (FilmViewer* viewer, wxWindow *parent)
: VideoView (viewer)
, _context (nullptr)
- , _have_storage (false)
, _vsync_enabled (false)
, _playing (false)
, _one_shot (false)
_thread.interrupt ();
_thread.join ();
} catch (...) {}
-
- glDeleteTextures (1, &_video_texture);
}
void
glViewport (0, 0, width, height);
check_gl_error ("glViewport");
- glBindTexture(GL_TEXTURE_2D, _video_texture);
glBindVertexArray(_vao);
check_gl_error ("glBindVertexArray");
glUniform1i(_fragment_type, _optimise_for_j2k ? 1 : 2);
void
GLVideoView::set_image (shared_ptr<const PlayerVideo> pv)
{
- auto image = _optimise_for_j2k ? pv->raw_image() : pv->image(bind(&PlayerVideo::force, _1, AV_PIX_FMT_RGB24), VideoRange::FULL, false, true);
+ auto video = _optimise_for_j2k ? pv->raw_image() : pv->image(bind(&PlayerVideo::force, _1, AV_PIX_FMT_RGB24), VideoRange::FULL, false, true);
- DCPOMATIC_ASSERT (!image->aligned());
+ DCPOMATIC_ASSERT (!video->aligned());
/** If _optimise_for_j2k is true we render a XYZ image, doing the colourspace
* conversion, scaling and video range conversion in the GL shader.
/* XXX: video range conversion */
/* XXX: subs */
- if (image->size() != _video_size) {
- _have_storage = false;
- }
-
- _video_size = image->size ();
- glPixelStorei (GL_UNPACK_ALIGNMENT, _optimise_for_j2k ? 2 : 1);
- check_gl_error ("glPixelStorei");
-
- auto const format = _optimise_for_j2k ? GL_UNSIGNED_SHORT : GL_UNSIGNED_BYTE;
-
- if (_have_storage) {
- glTexSubImage2D (GL_TEXTURE_2D, 0, 0, 0, _video_size->width, _video_size->height, GL_RGB, format, image->data()[0]);
- check_gl_error ("glTexSubImage2D");
- } else {
- glTexImage2D (GL_TEXTURE_2D, 0, _optimise_for_j2k ? GL_RGBA12 : GL_RGBA8, _video_size->width, _video_size->height, 0, GL_RGB, format, image->data()[0]);
- check_gl_error ("glTexImage2D");
+ auto const changed = _video_texture->set (video);
+ if (changed) {
auto const canvas_size = _canvas_size.load();
int const canvas_width = canvas_size.GetWidth();
int const canvas_height = canvas_size.GetHeight();
- float const image_x = float(_video_size->width) / canvas_width;
- float const image_y = float(_video_size->height) / canvas_height;
+ float const video_x = float(video->size().width) / canvas_width;
+ float const video_y = float(video->size().height) / canvas_height;
auto x_pixels_to_gl = [canvas_width](int x) {
return (x * 2.0f / canvas_width) - 1.0f;
auto inter_position = player_video().first->inter_position();
auto inter_size = player_video().first->inter_size();
- float const border_x1 = x_pixels_to_gl (inter_position.x) + 1.0f - image_x;
- float const border_y1 = y_pixels_to_gl (inter_position.y) + 1.0f - image_y;
- float const border_x2 = x_pixels_to_gl (inter_position.x + inter_size.width) + 1.0f - image_x;
- float const border_y2 = y_pixels_to_gl (inter_position.y + inter_size.height) + 1.0f - image_y;
+ float const border_x1 = x_pixels_to_gl (inter_position.x) + 1.0f - video_x;
+ float const border_y1 = y_pixels_to_gl (inter_position.y) + 1.0f - video_y;
+ float const border_x2 = x_pixels_to_gl (inter_position.x + inter_size.width) + 1.0f - video_x;
+ float const border_y2 = y_pixels_to_gl (inter_position.y + inter_size.height) + 1.0f - video_y;
float vertices[] = {
// positions // texture coords
- image_x, image_y, 0.0f, 1.0f, 0.0f, // video texture top right (index 0)
- image_x, -image_y, 0.0f, 1.0f, 1.0f, // video texture bottom right (index 1)
- -image_x, -image_y, 0.0f, 0.0f, 1.0f, // video texture bottom left (index 2)
- -image_x, image_y, 0.0f, 0.0f, 0.0f, // video texture top left (index 3)
+ video_x, video_y, 0.0f, 1.0f, 0.0f, // video texture top right (index 0)
+ video_x, -video_y, 0.0f, 1.0f, 1.0f, // video texture bottom right (index 1)
+ -video_x, -video_y, 0.0f, 0.0f, 1.0f, // video texture bottom left (index 2)
+ -video_x, video_y, 0.0f, 0.0f, 0.0f, // video texture top left (index 3)
border_x1, border_y1, 0.0f, 0.0f, 0.0f, // border bottom left (index 4)
border_x1, border_y2, 0.0f, 0.0f, 0.0f, // border top left (index 5)
border_x2, border_y2, 0.0f, 0.0f, 0.0f, // border top right (index 6)
/* Set the vertex shader's input data (GL_ARRAY_BUFFER) */
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
check_gl_error ("glBufferData");
-
- _have_storage = true;
}
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
_vsync_enabled = true;
#endif
- glGenTextures (1, &_video_texture);
- check_gl_error ("glGenTextures");
- glBindTexture (GL_TEXTURE_2D, _video_texture);
- check_gl_error ("glBindTexture");
+ _video_texture.reset(new Texture(_optimise_for_j2k ? 2 : 1));
+ _video_texture->bind();
while (true) {
boost::mutex::scoped_lock lm (_playing_mutex);
_thread_work_condition.notify_all ();
}
+
+Texture::Texture (GLint unpack_alignment)
+ : _unpack_alignment (unpack_alignment)
+{
+ glGenTextures (1, &_name);
+ check_gl_error ("glGenTextures");
+}
+
+
+Texture::~Texture ()
+{
+ glDeleteTextures (1, &_name);
+}
+
+
+void
+Texture::bind ()
+{
+ glBindTexture(GL_TEXTURE_2D, _name);
+ check_gl_error ("glBindTexture");
+}
+
+
+bool
+Texture::set (shared_ptr<const Image> image)
+{
+ auto const create = !_size || image->size() != _size;
+ _size = image->size();
+
+ glPixelStorei (GL_UNPACK_ALIGNMENT, _unpack_alignment);
+ check_gl_error ("glPixelStorei");
+
+ auto const format = image->pixel_format() == AV_PIX_FMT_RGB24 ? GL_UNSIGNED_BYTE : GL_UNSIGNED_SHORT;
+ auto const internal_format = image->pixel_format() == AV_PIX_FMT_RGB24 ? GL_RGBA8 : GL_RGBA12;
+
+ if (create) {
+ glTexImage2D (GL_TEXTURE_2D, 0, internal_format, _size->width, _size->height, 0, GL_RGB, format, image->data()[0]);
+ check_gl_error ("glTexImage2D");
+ } else {
+ glTexSubImage2D (GL_TEXTURE_2D, 0, 0, 0, _size->width, _size->height, GL_RGB, format, image->data()[0]);
+ check_gl_error ("glTexSubImage2D");
+ }
+
+ return create;
+}
+