-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain_window.cpp
122 lines (102 loc) · 3.04 KB
/
main_window.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
#include <stdio.h>
#include <GLFW/glfw3.h>
#include "decoder.h"
void framebuffer_size_callback(GLFWwindow *window, int width, int height)
{
glViewport(0, 0, width, height);
}
void processExitInput(GLFWwindow *window)
{
if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
glfwSetWindowShouldClose(window, true);
}
int main(int argc, const char **argv)
{
GLFWwindow *window;
if (!glfwInit())
{
err_log("Couldn't init GLFW");
return 1;
}
decoder_t dec;
if (!quicsy_decoder_open(&dec, argv[1]))
{
err_log("Couldn't open video file");
return 1;
}
log("opening the input file (%s) and loading format (container) header", argv[1]);
window = glfwCreateWindow(dec.width, dec.height, "QUIC streamer", NULL, NULL);
if (window == NULL)
{
err_log("Window: Couldn't open window");
glfwTerminate();
return 1;
}
glfwMakeContextCurrent(window);
// Generate texture
GLuint tex_handle;
glGenTextures(1, &tex_handle);
glBindTexture(GL_TEXTURE_2D, tex_handle);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
// Allocate frame buffer
const int frame_width = dec.width;
const int frame_height = dec.height;
uint8_t *frame_data = new uint8_t[frame_width * frame_height * 4];
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
while (!glfwWindowShouldClose(window))
{
processExitInput(window);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Set up orphographic projection
int window_width, window_height;
glfwGetFramebufferSize(window, &window_width, &window_height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, window_width, window_height, 1, -1, 1);
glMatrixMode(GL_MODELVIEW);
// Read a new frame and load it into texture
int64_t pts;
if (!quicsy_decoder_read_frame(&dec, frame_data, &pts))
{
err_log("Couldn't load video frame\n");
return false;
}
static bool first_frame = true;
if (first_frame)
{
glfwSetTime(0.0);
first_frame = false;
}
double pt_in_seconds = pts * (double)dec.time_base.num / (double)dec.time_base.den;
while (pt_in_seconds > glfwGetTime())
{
glfwWaitEventsTimeout(pt_in_seconds - glfwGetTime());
}
glBindTexture(GL_TEXTURE_2D, tex_handle);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, frame_width, frame_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, frame_data);
// Render whatever you want
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, tex_handle);
glBegin(GL_QUADS);
glTexCoord2d(0, 0);
glVertex2i(0,0);
glTexCoord2d(1, 0);
glVertex2i(window_width, 0);
glTexCoord2d(1, 1);
glVertex2i(window_width, window_height);
glTexCoord2d(0, 1);
glVertex2i(0, window_height);
glEnd();
glDisable(GL_TEXTURE_2D);
glfwSwapBuffers(window);
glfwPollEvents();
}
quicsy_decoder_close(&dec);
glfwTerminate();
return 0;
}