diff options
-rw-r--r-- | libmkv/nut-3.c | 98 |
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; |