UltraGrid
UltraGrid Low-Latency High-Resolution Transmission System
Loading...
Searching...
No Matches
thumbnailgen.cpp
Go to the documentation of this file.
1#include <iostream>
2#include <filesystem>
3#include <string_view>
4#include <memory>
5#include <chrono>
6#include <cassert>
7#include <stdio.h>
8#include <jpeglib.h>
9#include "ipc_frame_unix.h"
10
11struct file_deleter { void operator()(FILE *f){ fclose(f); } };
12using File_uniq = std::unique_ptr<FILE, file_deleter>;
13
15public:
17 compress_ctx.err = jpeg_std_error(&err_mgr);
18 jpeg_create_compress(&compress_ctx);
19
20 compress_ctx.input_components = 3;
21 compress_ctx.in_color_space = JCS_RGB;
22 jpeg_set_defaults(&compress_ctx);
23 }
24
25 Img_writer(const Img_writer&) = delete;
26 Img_writer& operator=(const Img_writer&) = delete;
27
29 jpeg_destroy_compress(&compress_ctx);
30 }
31
32 bool write_img(Ipc_frame *f, const std::string& path){
34 File_uniq outfile(fopen(path.c_str(), "wb"));
35 if (!outfile) {
36 fprintf(stderr, "Can't open output file %s\n", path.c_str());
37 return false;
38 }
39 jpeg_stdio_dest(&compress_ctx, outfile.get());
40
41 compress_ctx.image_width = f->header.width;
42 compress_ctx.image_height = f->header.height;
43
44 jpeg_start_compress(&compress_ctx, true);
45 while(compress_ctx.next_scanline < compress_ctx.image_height){
46 JSAMPROW row = (unsigned char *) f->data + compress_ctx.next_scanline * f->header.width * 3;
47 jpeg_write_scanlines(&compress_ctx, &row, 1);
48 }
49 jpeg_finish_compress(&compress_ctx);
50
51 return true;
52 }
53
54private:
55 struct jpeg_compress_struct compress_ctx;
56 struct jpeg_error_mgr err_mgr;
57};
58
59int main(int argc, char **argv){
60 if(argc != 4){
61 fprintf(stderr, "Usage: %s <socket path> <output path> <fps>\n", argv[0]);
62 return 1;
63 }
64
66 Ipc_frame_uniq ipc_frame(ipc_frame_new());
67
68 Img_writer img_writer;
69
70 using clock = std::chrono::steady_clock;
71 auto frame_time = std::chrono::duration_cast<clock::duration>(std::chrono::duration<double>(1 / std::stod(argv[3])));
72 auto next_frame = clock::now();
73
74 while(true){
75 printf("Waiting for connection...\n");
77 printf("Connected...\n");
78 while(ipc_frame_reader_read(reader.get(), ipc_frame.get())){
79 auto now = clock::now();
80 if(now < next_frame)
81 continue;
82
83 std::string path = argv[2];
84 std::string tmp_path = path + ".swp";
85
86 img_writer.write_img(ipc_frame.get(), tmp_path);
87 std::filesystem::rename(tmp_path, path);
88
89 next_frame = std::max(next_frame + frame_time, now);
90 }
91 fprintf(stderr, "Failed to read frame\n");
92 }
93
94 return 0;
95}
struct jpeg_error_mgr err_mgr
Img_writer & operator=(const Img_writer &)=delete
struct jpeg_compress_struct compress_ctx
bool write_img(Ipc_frame *f, const std::string &path)
Img_writer(const Img_writer &)=delete
Ipc_frame * ipc_frame_new()
Definition ipc_frame.cpp:48
std::unique_ptr< Ipc_frame, Ipc_frame_deleter > Ipc_frame_uniq
Definition ipc_frame.h:40
@ IPC_FRAME_COLOR_RGB
Definition ipc_frame.h:13
void ipc_frame_reader_wait_connect(struct Ipc_frame_reader *reader)
Ipc_frame_reader * ipc_frame_reader_new(const char *path)
bool ipc_frame_reader_read(Ipc_frame_reader *reader, Ipc_frame *dst)
std::unique_ptr< Ipc_frame_reader, Ipc_frame_reader_deleter > Ipc_frame_reader_uniq
enum Ipc_frame_color_spec color_spec
Definition ipc_frame.h:20
Ipc_frame_header header
Definition ipc_frame.h:24
char * data
Definition ipc_frame.h:25
void operator()(FILE *f)
std::unique_ptr< FILE, file_deleter > File_uniq