summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke T. Shumaker <lukeshu@lukeshu.com>2025-02-17 18:58:43 -0700
committerLuke T. Shumaker <lukeshu@lukeshu.com>2025-02-17 18:58:43 -0700
commit0160335e1fd0e8d6d1699cca0385ecb5d6a43998 (patch)
tree10e9ed2f226e9dbd912c789a117d9d36e3adf306
parent0506ec74712be278ce88d8227987a3d8d5b8135a (diff)
wip
-rw-r--r--libmkv/nut-3.c98
1 files changed, 52 insertions, 46 deletions
diff --git a/libmkv/nut-3.c b/libmkv/nut-3.c
index 6a7ac4a..cc40929 100644
--- a/libmkv/nut-3.c
+++ b/libmkv/nut-3.c
@@ -238,6 +238,7 @@ bool app_write_intro(int fd, struct app_state *state, uint64_t time_ns) {
append(&out, nut_file_id_string, sizeof(nut_file_id_string));
/* main_header ********************************************************/
+#define BOGUS 0
nut_append_vu(&pkt, 3); /*! version */
nut_append_vu(&pkt, 1); /*! stream_count */
@@ -252,55 +253,57 @@ bool app_write_intro(int fd, struct app_state *state, uint64_t time_ns) {
/* frame codes ************************************/
/* "A muxer SHOULD mark [frame codes] 0x00 and 0xFF as invalid" */
-#define BOGUS 0
+#define SIZE_MSB_MUL 0x2000 /* must be less than 0x4000 */
+#define COMMON_FLAGS NUT_FRAMEFLAG_KEY|NUT_FRAMEFLAG_SIZE_MSB|NUT_FRAMEFLAG_CHECKSUM|NUT_FRAMEFLAG_SM_DATA
/* frame_code=0 (invalid) */
- nut_append_vu(&pkt, NUT_FRAMEFLAG_INVALID); /*! flags */
- nut_append_vu(&pkt, 2); /*! field_count */
- nut_append_vu(&pkt, BOGUS); /*! 0: fields.pts */
- nut_append_vu(&pkt, 1); /*! 1: fields.mul */
+ nut_append_vu(&pkt, NUT_FRAMEFLAG_INVALID); /*! flags */
+ nut_append_vu(&pkt, 2); /*! field_count */
+ nut_append_vu(&pkt, BOGUS); /*! 0: fields.pts */
+ nut_append_vu(&pkt, 1); /*! 1: fields.size_msb_nul */
/* frame_code=1 (640x480) */
- nut_append_vu(&pkt, NUT_FRAMEFLAG_KEY|NUT_FRAMEFLAG_SIZE_MSB|NUT_FRAMEFLAG_SM_DATA); /*! flags */
- nut_append_vu(&pkt, 8); /*! field_count */
- nut_append_vu(&pkt, BOGUS); /*! 0: fields.pts */
- nut_append_vu(&pkt, 0x2000); /*! 1: fields.mul */
- nut_append_vu(&pkt, 0); /*! 2: fields.stream */
- nut_append_vu(&pkt, (640*(480/2))&0x3FFF); /*! 3: fields.size_lsb */
- nut_append_vu(&pkt, 0); /*! 4: fields.reserved */
- nut_append_vu(&pkt, 1); /*! 5: fields.count */
- nut_append_vs(&pkt, NUT_UNKNOWN_MATCH_TIME); /*! 6: fields.match */
- nut_append_vu(&pkt, 1); /*! 7: fields.elision_header */
+ nut_append_vu(&pkt, COMMON_FLAGS); /*! flags */
+ nut_append_vu(&pkt, 8); /*! field_count */
+ nut_append_vu(&pkt, BOGUS); /*! 0: fields.pts */
+ nut_append_vu(&pkt, SIZE_MSB_MUL); /*! 1: fields.size_msb_nul */
+ nut_append_vu(&pkt, 0); /*! 2: fields.stream */
+ nut_append_vu(&pkt, (640*(480/2))%SIZE_MSB_MUL); /*! 3: fields.size_lsb */
+ nut_append_vu(&pkt, 0); /*! 4: fields.reserved */
+ nut_append_vu(&pkt, 1); /*! 5: fields.count */
+ nut_append_vs(&pkt, NUT_UNKNOWN_MATCH_TIME); /*! 6: fields.match */
+ nut_append_vu(&pkt, 1); /*! 7: fields.elision_header */
/* frame_code=2 (720x480) */
- nut_append_vu(&pkt, NUT_FRAMEFLAG_KEY|NUT_FRAMEFLAG_SIZE_MSB|NUT_FRAMEFLAG_SM_DATA); /*! flags */
- nut_append_vu(&pkt, 8); /*! field_count */
- nut_append_vu(&pkt, BOGUS); /*! 0: fields.pts */
- nut_append_vu(&pkt, 0x2000); /*! 1: fields.mul */
- nut_append_vu(&pkt, 0); /*! 2: fields.stream */
- nut_append_vu(&pkt, (720*(480/2))&0x3FFF); /*! 3: fields.size_lsb */
- nut_append_vu(&pkt, 0); /*! 4: fields.reserved */
- nut_append_vu(&pkt, 1); /*! 5: fields.count */
- nut_append_vs(&pkt, NUT_UNKNOWN_MATCH_TIME); /*! 6: fields.match */
- nut_append_vu(&pkt, 2); /*! 7: fields.elision_header */
+ nut_append_vu(&pkt, COMMON_FLAGS); /*! flags */
+ nut_append_vu(&pkt, 8); /*! field_count */
+ nut_append_vu(&pkt, BOGUS); /*! 0: fields.pts */
+ nut_append_vu(&pkt, SIZE_MSB_MUL); /*! 1: fields.size_msb_mul */
+ nut_append_vu(&pkt, 0); /*! 2: fields.stream */
+ nut_append_vu(&pkt, (720*(480/2))%SIZE_MSB_MUL); /*! 3: fields.size_lsb */
+ nut_append_vu(&pkt, 0); /*! 4: fields.reserved */
+ nut_append_vu(&pkt, 1); /*! 5: fields.count */
+ nut_append_vs(&pkt, NUT_UNKNOWN_MATCH_TIME); /*! 6: fields.match */
+ nut_append_vu(&pkt, 2); /*! 7: fields.elision_header */
/* frame_code=3 (720x576) */
- nut_append_vu(&pkt, NUT_FRAMEFLAG_KEY|NUT_FRAMEFLAG_SIZE_MSB|NUT_FRAMEFLAG_SM_DATA); /*! flags */
- nut_append_vu(&pkt, 8); /*! field_count */
- nut_append_vu(&pkt, BOGUS); /*! 0: fields.pts */
- nut_append_vu(&pkt, 0x2000); /*! 1: fields.mul */
- nut_append_vu(&pkt, 0); /*! 2: fields.stream */
- nut_append_vu(&pkt, (720*(576/2))&0x3FFF); /*! 3: fields.size_lsb */
- nut_append_vu(&pkt, 0); /*! 4: fields.reserved */
- nut_append_vu(&pkt, 1); /*! 5: fields.count */
- nut_append_vs(&pkt, NUT_UNKNOWN_MATCH_TIME); /*! 6: fields.match */
- nut_append_vu(&pkt, 2); /*! 7: fields.elision_header */
+ nut_append_vu(&pkt, COMMON_FLAGS); /*! flags */
+ nut_append_vu(&pkt, 8); /*! field_count */
+ nut_append_vu(&pkt, BOGUS); /*! 0: fields.pts */
+ nut_append_vu(&pkt, 0x2000); /*! 1: fields.size_msb_nul */
+ nut_append_vu(&pkt, 0); /*! 2: fields.stream */
+ nut_append_vu(&pkt, (720*(576/2))%SIZE_MSB_MUL); /*! 3: fields.size_lsb */
+ nut_append_vu(&pkt, 0); /*! 4: fields.reserved */
+ nut_append_vu(&pkt, 1); /*! 5: fields.count */
+ nut_append_vs(&pkt, NUT_UNKNOWN_MATCH_TIME); /*! 6: fields.match */
+ nut_append_vu(&pkt, 2); /*! 7: fields.elision_header */
/* frame_code=4-255 (invalid) */
- nut_append_vu(&pkt, NUT_FRAMEFLAG_INVALID); /*! flags */
- nut_append_vu(&pkt, 2); /*! field_count */
- nut_append_vu(&pkt, BOGUS); /*! 0: fields.pts */
- nut_append_vu(&pkt, 256-4-1); /*! 1: fields.mul */
+ nut_append_vu(&pkt, NUT_FRAMEFLAG_INVALID); /*! flags */
+ nut_append_vu(&pkt, 2); /*! field_count */
+ nut_append_vu(&pkt, BOGUS); /*! 0: fields.pts */
+ nut_append_vu(&pkt, 256-4-1); /*! 1: fields.size_msb_nul */
+#undef COMMON_FLAGS
/* elision headers ********************************/
nut_append_vu(&pkt, 3); /*! header_count_minus_1 */
@@ -347,7 +350,7 @@ bool app_write_intro(int fd, struct app_state *state, uint64_t time_ns) {
nut_append_vb(&pkt, "BGR\x08", 4); /*! fourcc */
nut_append_vu(&pkt, 0); /*! time_base_id */
nut_append_vu(&pkt, BOGUS); /*! msb_pts_shift (only relevant if FRAMEFLAG_CODED_PTS) */
- nut_append_vu(&pkt, BOGUS); /*! max_pts_distance (only relevant if FRAMEFLAG_CODED_PTS) */
+ nut_append_vu(&pkt, BOGUS); /*! max_pts_distance (all frames have a checksum) */
nut_append_vu(&pkt, 0); /*! decode_delay */
nut_append_vu(&pkt, 0); /*! stream_flags */
nut_append_vb(&pkt, NULL, 0); /*! codec_specific_data */
@@ -392,11 +395,14 @@ bool app_write_frame(int fd, struct app_state *state, uint64_t time_ns, enum app
nut_append_packet(&out, nut_startcode_syncpoint, pkt.dat, pkt.len);
/* frame header */
- nut_append_u8(&out, 1+res); /*! frame_code */
- nut_append_vu(&out, (framebuffer_size>>13) & ~UINT64_C(1)); /*! data_size_msb */
+ uint64_t frame_beg = out.len;
+ nut_append_u8(&out, 1+res); /*! frame_code */
+ nut_append_vu(&out, framebuffer_size/SIZE_MSB_MUL); /*! data_size_msb */
+ nut_append_u32(&out, nut_crc32(&out.dat[frame_beg], out.len - frame_beg)); /*! checksum */
/* side_data and meta_data come from elision headers */
/* flush */
+ fprintf(stderr, "frame_overhead=%zu\n", out.len);
bool err = xwrite(fd, out.dat, out.len);
free(out.dat);
free(pkt.dat);
@@ -478,18 +484,18 @@ int main() {
uint8_t framebuffer[720*(576/2)];
-#define MUL 10
+#define SCALE 10
for (int i = 0; i < 10; i++) {
memset(framebuffer, 0, sizeof(framebuffer));
- for (int y = 0; y < 4*MUL; y++) {
+ for (int y = 0; y < 4*SCALE; y++) {
int width;
switch (i%3) {
case APP_RES_640_480: width = 640; break;
case APP_RES_720_480: width = 720; break;
case APP_RES_720_576: width = 720; break;
}
- for (int x = 0; x < 8*MUL; x++)
- framebuffer[(y*width)+x] = font[i][((y/MUL)*8)+(x/MUL)] == ' ' ? 0xFF : 0x00;
+ for (int x = 0; x < 8*SCALE; x++)
+ framebuffer[(y*width)+x] = font[i][((y/SCALE)*8)+(x/SCALE)] == ' ' ? 0b11000000 : 0b00000011;
}
if (app_write_frame(1, &state, ((uint64_t)i)*((uint64_t)i)*1000000000ULL, i%3, framebuffer))
return 1;