diff options
author | Luke T. Shumaker <lukeshu@lukeshu.com> | 2025-02-20 16:03:05 -0700 |
---|---|---|
committer | Luke T. Shumaker <lukeshu@lukeshu.com> | 2025-02-20 16:03:05 -0700 |
commit | f5ad1399aec565f9562cee9df21f24124a85c9e0 (patch) | |
tree | a0c06bb92537eb61c7ff222afa0ed78c25b705d1 /libmkv/nut-generate.c | |
parent | 690f6f81582dc5304f0e49dab55c68eceba460b0 (diff) |
wip
Diffstat (limited to 'libmkv/nut-generate.c')
-rw-r--r-- | libmkv/nut-generate.c | 92 |
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; } |