Browse Source

Merge pull request #143 from tsoding/141

(#141) Sync OpenGL preview with the FPS
Alexey Kutepov 5 years ago
parent
commit
68d6465402
3 changed files with 31 additions and 12 deletions
  1. 22 4
      src/vodus_encoder.cpp
  2. 7 6
      src/vodus_encoder.hpp
  3. 2 2
      src/vodus_main.cpp

+ 22 - 4
src/vodus_encoder.cpp

@@ -1,3 +1,4 @@
+#include <unistd.h>
 #include "vodus_encoder.hpp"
 #include "vodus_encoder.hpp"
 
 
 void encode_avframe(AVCodecContext *context, AVFrame *frame, AVPacket *pkt, FILE *outfile)
 void encode_avframe(AVCodecContext *context, AVFrame *frame, AVPacket *pkt, FILE *outfile)
@@ -35,7 +36,7 @@ void slap_image32_onto_avframe(Image32 frame_image32, AVFrame *avframe)
     }
     }
 }
 }
 
 
-void avencoder_encode(AVEncoder_Context *context, Image32 surface, int frame_index)
+void avencoder_encode(AVEncoder_Context *context, Video_Params, Image32 surface, int frame_index)
 {
 {
     slap_image32_onto_avframe(surface, context->frame);
     slap_image32_onto_avframe(surface, context->frame);
     context->frame->pts = frame_index;
     context->frame->pts = frame_index;
@@ -103,7 +104,7 @@ AVEncoder_Context *new_avencoder_context(Video_Params params, const char *output
     return result;
     return result;
 }
 }
 
 
-void pngencoder_encode(PNGEncoder_Context *context, Image32 surface, int frame_index)
+void pngencoder_encode(PNGEncoder_Context *context, Video_Params, Image32 surface, int frame_index)
 {
 {
     char buffer[1024];
     char buffer[1024];
     String_Buffer path = {sizeof(buffer), buffer};
     String_Buffer path = {sizeof(buffer), buffer};
@@ -242,7 +243,16 @@ Preview_Context *new_preview_context(Video_Params params)
     return context;
     return context;
 }
 }
 
 
-void previewencoder_encode(Preview_Context *context, Image32 surface, int frame_index)
+void delay(size_t milliseconds)
+{
+#ifdef _WIN32
+#error "TODO(#144): delay is not implemented for windows"
+#else
+    usleep(milliseconds * 1000);
+#endif // _WIN32
+}
+
+void previewencoder_encode(Preview_Context *context, Video_Params params, Image32 surface, int frame_index)
 {
 {
     if (glfwWindowShouldClose(context->window)) {
     if (glfwWindowShouldClose(context->window)) {
         // TODO(#140): encoder does not provide a mechanism to exit prematurely
         // TODO(#140): encoder does not provide a mechanism to exit prematurely
@@ -261,10 +271,18 @@ void previewencoder_encode(Preview_Context *context, Image32 surface, int frame_
                  surface.pixels);
                  surface.pixels);
     glGenerateMipmap(GL_TEXTURE_2D);
     glGenerateMipmap(GL_TEXTURE_2D);
 
 
-    // TODO(#141): Preview is not synced with real time
     // TODO(#142): Preview does not allow to pause and move backward/forward
     // TODO(#142): Preview does not allow to pause and move backward/forward
 
 
     glDrawArrays(GL_QUADS, 0, 4);
     glDrawArrays(GL_QUADS, 0, 4);
     glfwSwapBuffers(context->window);
     glfwSwapBuffers(context->window);
     glfwPollEvents();
     glfwPollEvents();
+
+    clock_t end = clock();
+    const auto delta_time = 1000 / params.fps;
+    assert(context->begin <= end);
+    const auto frame_time = (size_t) (end - context->begin);
+    if (delta_time >= frame_time) {
+        delay(delta_time - frame_time);
+    }
+    context->begin = end;
 }
 }

+ 7 - 6
src/vodus_encoder.hpp

@@ -1,16 +1,16 @@
 #ifndef VODUS_ENCODER_HPP_
 #ifndef VODUS_ENCODER_HPP_
 #define VODUS_ENCODER_HPP_
 #define VODUS_ENCODER_HPP_
 
 
-typedef void (*Encode_Func)(void *context, Image32 surface, int frame_index);
+typedef void (*Encode_Func)(void *context, Video_Params params, Image32 surface, int frame_index);
 
 
 struct Encoder
 struct Encoder
 {
 {
     void *context;
     void *context;
     Encode_Func encode_func;
     Encode_Func encode_func;
 
 
-    void encode(Image32 surface, int frame_index)
+    void encode(Video_Params params, Image32 surface, int frame_index)
     {
     {
-        encode_func(context, surface, frame_index);
+        encode_func(context, params, surface, frame_index);
     }
     }
 };
 };
 
 
@@ -25,22 +25,23 @@ struct AVEncoder_Context
 
 
 AVEncoder_Context *new_avencoder_context(Video_Params params, const char *output_filepath);
 AVEncoder_Context *new_avencoder_context(Video_Params params, const char *output_filepath);
 void free_avencoder_context(AVEncoder_Context *context);
 void free_avencoder_context(AVEncoder_Context *context);
-void avencoder_encode(AVEncoder_Context *context, Image32 surface, int frame_index);
+void avencoder_encode(AVEncoder_Context *context, Video_Params params, Image32 surface, int frame_index);
 
 
 struct PNGEncoder_Context
 struct PNGEncoder_Context
 {
 {
     String_View output_folder_path;
     String_View output_folder_path;
 };
 };
 
 
-void pngencoder_encode(PNGEncoder_Context *context, Image32 surface, int frame_index);
+void pngencoder_encode(PNGEncoder_Context *context, Video_Params params, Image32 surface, int frame_index);
 
 
 struct Preview_Context
 struct Preview_Context
 {
 {
     GLFWwindow *window;
     GLFWwindow *window;
+    clock_t begin;
 };
 };
 
 
 Preview_Context *new_preview_context(Video_Params parsm);
 Preview_Context *new_preview_context(Video_Params parsm);
 
 
-void previewencoder_encode(Preview_Context *context, Image32 surface, int frame_index);
+void previewencoder_encode(Preview_Context *context, Video_Params params, Image32 surface, int frame_index);
 
 
 #endif  // VODUS_ENCODER_HPP_
 #endif  // VODUS_ENCODER_HPP_

+ 2 - 2
src/vodus_main.cpp

@@ -39,7 +39,7 @@ void sample_chat_log_animation(Message *messages,
 
 
         fill_image32_with_color(surface, params.background_color);
         fill_image32_with_color(surface, params.background_color);
         message_buffer->render(surface, face, emote_cache, params);
         message_buffer->render(surface, face, emote_cache, params);
-        encoder.encode(surface, frame_index);
+        encoder.encode(params, surface, frame_index);
 
 
         t += VODUS_DELTA_TIME_SEC;
         t += VODUS_DELTA_TIME_SEC;
         emote_cache->update_gifs(VODUS_DELTA_TIME_SEC);
         emote_cache->update_gifs(VODUS_DELTA_TIME_SEC);
@@ -54,7 +54,7 @@ void sample_chat_log_animation(Message *messages,
 
 
         emote_cache->update_gifs(VODUS_DELTA_TIME_SEC);
         emote_cache->update_gifs(VODUS_DELTA_TIME_SEC);
         message_buffer->update(VODUS_DELTA_TIME_SEC, face, emote_cache, params);
         message_buffer->update(VODUS_DELTA_TIME_SEC, face, emote_cache, params);
-        encoder.encode(surface, frame_index);
+        encoder.encode(params, surface, frame_index);
 
 
         t += VODUS_DELTA_TIME_SEC;
         t += VODUS_DELTA_TIME_SEC;
         print(stdout, "\rRendered ", (int) roundf(t), "/", (int) roundf(total_t), " seconds");
         print(stdout, "\rRendered ", (int) roundf(t), "/", (int) roundf(total_t), " seconds");