summaryrefslogtreecommitdiff
path: root/libmkv/nut-generate.c
diff options
context:
space:
mode:
authorLuke T. Shumaker <lukeshu@lukeshu.com>2025-02-20 16:03:05 -0700
committerLuke T. Shumaker <lukeshu@lukeshu.com>2025-02-20 16:03:05 -0700
commitf5ad1399aec565f9562cee9df21f24124a85c9e0 (patch)
treea0c06bb92537eb61c7ff222afa0ed78c25b705d1 /libmkv/nut-generate.c
parent690f6f81582dc5304f0e49dab55c68eceba460b0 (diff)
wip
Diffstat (limited to 'libmkv/nut-generate.c')
-rw-r--r--libmkv/nut-generate.c92
1 files changed, 28 insertions, 64 deletions
diff --git a/libmkv/nut-generate.c b/libmkv/nut-generate.c
index c52d8c1..02f9a3d 100644
--- a/libmkv/nut-generate.c
+++ b/libmkv/nut-generate.c
@@ -21,60 +21,11 @@
#include <stdlib.h> /* for realloc(), free() */
#include <string.h> /* for memcpy(), memset() */
#include <unistd.h> /* for write() */
+#include <fcntl.h> /* for open() */
/* Generic ********************************************************************/
-#define LM_ARRAY_LEN(ary) (sizeof(ary)/sizeof((ary)[0]))
-#define LM_CEILDIV(n, d) ( ((n)+(d)-1) / (d) )
-#define LM_NEXT_POWER_OF_2(x) ( (x) ? 1ULL<<((sizeof(unsigned long long)*8)-__builtin_clzll(x)) : 1)
-#define LM_CAT2(a, b) a ## b
-#define LM_CAT2_(a, b) LM_CAT2(a, b)
-#define assert_notreached(msg) assert(false)
-
-struct buf {
- uint8_t *dat;
- size_t len;
- size_t cap;
-};
-
-void append(struct buf *buf, void *dat, size_t len) {
- assert(buf);
- assert(len == 0 || dat);
-
- if (buf->len + len > buf->cap) {
- buf->cap = LM_NEXT_POWER_OF_2(buf->len + len);
- buf->dat = realloc(buf->dat, buf->cap);
- assert(buf->dat);
- }
- memcpy(&buf->dat[buf->len], dat, len);
- buf->len += len;
-}
-
-void append_u32be(struct buf *buf, uint32_t val) {
- assert(buf);
-
- uint8_t dat[4] = {
- (val>>(8*3))&0xFF,
- (val>>(8*2))&0xFF,
- (val>>(8*1))&0xFF,
- (val>>(8*0))&0xFF,
- };
- append(buf, dat, sizeof(dat));
-}
-
-bool xwrite(int fd, uint8_t *dat, size_t len) {
- assert(len == 0 || dat);
-
- for (size_t done = 0; done < len;) {
- ssize_t n = write(fd, &dat[done], len-done);
- if (n < 0) {
- perror("write");
- return true;
- }
- done += n;
- }
- return false;
-}
+#include "common.h"
/* NUT ************************************************************************/
@@ -259,9 +210,11 @@ size_t app_res_fb_size(enum app_res res) {
struct app_state {
enum app_res res;
+ uint64_t len;
+ uint64_t last_syncpoint;
};
-void app_append_intro(struct buf *out, uint64_t time_ns, enum app_res res) {
+void app_append_intro(struct buf *out, enum app_res res) {
struct buf pkt = {0};
unsigned int frame_code = 0;
#define INC_FRAME_CODE() do { frame_code++; if (frame_code == 'N') frame_code++; } while(0)
@@ -273,8 +226,7 @@ void app_append_intro(struct buf *out, uint64_t time_ns, enum app_res res) {
pkt.len = 0;
/* head *******************************************/
- nut_append_vu(&pkt, 4); /*! version */
- nut_append_vu(&pkt, 0); /*! minor_version */
+ nut_append_vu(&pkt, 3); /*! version */
nut_append_vu(&pkt, 1); /*! stream_count */
nut_append_vu(&pkt, /*! max_distance */
APP_FRAME_MAX_HEADER +
@@ -322,7 +274,6 @@ void app_append_intro(struct buf *out, uint64_t time_ns, enum app_res res) {
/* tail *******************************************/
nut_append_vu(&pkt, 0); /*! header_count_minus_1 */
- nut_append_vu(&pkt, NUT_MAINFLAG_PIPE_MODE); /*! main_flags */
nut_append_packet(out, nut_startcode_main, pkt.dat, pkt.len);
@@ -346,14 +297,6 @@ void app_append_intro(struct buf *out, uint64_t time_ns, enum app_res res) {
nut_append_packet(out, nut_startcode_stream, pkt.dat, pkt.len);
- /* syncpoint **********************************************************/
- pkt.len = 0;
-
- nut_append_vu(&pkt, time_ns); /*! global_key_pts */
- nut_append_vu(&pkt, 0); /*! back_ptr_div16 */
-
- nut_append_packet(out, nut_startcode_syncpoint, pkt.dat, pkt.len);
-
/* flush **************************************************************/
#undef BOGUS
@@ -368,10 +311,21 @@ bool app_write_frame(int fd, struct app_state *state, uint64_t time_ns, enum app
struct buf pkt = {0};
if (res != state->res) {
- app_append_intro(&out, time_ns, res);
+ app_append_intro(&out, res);
state->res = res;
}
+ /* syncpoint packet ***************************************************/
+ pkt.len = 0;
+ uint64_t syncpoint_beg = state->len + out.len;
+
+ nut_append_vu(&pkt, time_ns); /*! global_key_pts */
+ nut_append_vu(&pkt, state->last_syncpoint /*! back_ptr_div16 */
+ ? (syncpoint_beg - state->last_syncpoint)/16
+ : 0);
+
+ nut_append_packet(&out, nut_startcode_syncpoint, pkt.dat, pkt.len);
+
/* frame header ( 1+10+1+4 = 16 bytes) */
uint64_t frame_beg = out.len;
nut_append_u8(&out, 1); /*! frame_code (1 byte) */
@@ -393,6 +347,8 @@ bool app_write_frame(int fd, struct app_state *state, uint64_t time_ns, enum app
/* return */
state->res = res;
+ state->len += out.len + app_res_fb_size(res);
+ state->last_syncpoint = syncpoint_beg;
return false;
}
@@ -466,6 +422,14 @@ int main() {
for (int y = 0; y < 4*SCALE; y++)
for (int x = 0; x < 8*SCALE; x++)
framebuffer[(y*app_res_w(res))+x] = font[i][((y/SCALE)*8)+(x/SCALE)] == ' ' ? 0b11000000 : 0b00000011;
+ if (i%2 == 0) {
+ char name[] = {'o', 'u', 't', '-', '0'+(i/2), '.', 'n', 'u', 't', '\0'};
+ int fd = open(name, O_WRONLY|O_TRUNC|O_CREAT, 0666);
+ dup2(fd, 1);
+ close(fd);
+ state.len = 0;
+ state.last_syncpoint = 0;
+ }
if (app_write_frame(1, &state, ((uint64_t)i)*1000000000ULL, res, framebuffer))
return 1;
}