diff --git a/terranmon.txt b/terranmon.txt index 26b3d27..73131ee 100644 --- a/terranmon.txt +++ b/terranmon.txt @@ -918,6 +918,7 @@ transmission capability, and region-of-interest coding. When motion coder is CDF 5/3, add 8 to the base version number. uint16 Width: picture width in pixels. Columns count for Videotex-only file. uint16 Height: picture height in pixels. Rows count for Videotex-only file. + If either width or height exceeds 65535 pixels, above two fields must be filled with zero and the dimension must be sourced from XDIM entry of the Extended Header uint8 FPS: frames per second. Use 0x00 for still pictures uint32 Total Frames: number of video frames - use 0 to denote not-finalised video stream @@ -1091,8 +1092,9 @@ The encoder supports following presets: uint16 Length of bytes * Bytes - + type_t Value + ### List of Keys - Uint64 BGNT: Video begin time in nanoseconds (must be equal to the value of the first Timecode packet) @@ -1100,6 +1102,7 @@ The encoder supports following presets: - Uint64 CDAT: Creation time in microseconds since UNIX Epoch (must be in UTC timezone) - Bytes VNDR: Name and version of the encoder (for Reference encoder: "Encoder-TAV 20251014 (list,of,features)") - Bytes FMPG: FFmpeg version (typically "ffmpeg version 8.0 Copyright (c) 2000-2025 the FFmpeg developers"; the first line of text FFmpeg emits) + - Bytes XDIM: Video dimension in ',' format. Mandatory if either width or height exceeds 65535 ## Extensible Packet Structure uint8 Packet Type @@ -1108,8 +1111,9 @@ The encoder supports following presets: uint8 Identifier[4] uint64 Length of the payload - + uint32 Length of the payload + * Payload ## Standard Metadata Payload Packet Structure @@ -1178,7 +1182,7 @@ temporal compression. uint32 Compressed Size * Zstd-compressed Motion Data - + uint32 Compressed Size * Zstd-compressed Unified Block Data @@ -1192,6 +1196,7 @@ The entire GOP (width×height×N_frames×3_channels) is preprocessed as a single int16 Y Non-zero Values[variable length] // All Y non-zero coefficients int16 Co Non-zero Values[variable length] // All Co non-zero coefficients int16 Cg Non-zero Values[variable length] // All Cg non-zero coefficients + uint32 EZBC Size for Y @@ -1200,6 +1205,7 @@ The entire GOP (width×height×N_frames×3_channels) is preprocessed as a single * EZBC Structure for Co uint32 EZBC Size for Cg * EZBC Structure for Cg + This layout enables Zstd to find patterns across both spatial and temporal dimensions, resulting in superior compression compared to per-frame encoding. @@ -2028,9 +2034,11 @@ A universal, simple cue designed to work as both playlist to cue up external fil uint16 String Length for relative path * Relative path + uint48 Offset to the file + -------------------------------------------------------------------------------- diff --git a/video_encoder/src/encoder_tav.c b/video_encoder/src/encoder_tav.c index 2de9db2..1f79e94 100644 --- a/video_encoder/src/encoder_tav.c +++ b/video_encoder/src/encoder_tav.c @@ -464,11 +464,13 @@ static int write_tav_header(FILE *fp, const tav_encoder_params_t *params, int ha fputc(version, fp); // Width (uint16_t, 2 bytes) - uint16_t width = (uint16_t)params->width; + // Write 0 if width exceeds 65535 (extended dimensions will be in XDIM) + uint16_t width = (params->width > 65535) ? 0 : (uint16_t)params->width; fwrite(&width, sizeof(uint16_t), 1, fp); // Height (uint16_t, 2 bytes) - uint16_t height = (uint16_t)params->height; + // Write 0 if height exceeds 65535 (extended dimensions will be in XDIM) + uint16_t height = (params->height > 65535) ? 0 : (uint16_t)params->height; fwrite(&height, sizeof(uint16_t), 1, fp); // FPS (uint8_t, 1 byte) - simplified to just fps_num @@ -529,15 +531,18 @@ static int write_tav_header(FILE *fp, const tav_encoder_params_t *params, int ha * Write Extended Header packet (0xEF) with metadata. * Returns the file offset of the ENDT value for later update, or -1 on error. */ -static long write_extended_header(cli_context_t *cli) { +static long write_extended_header(cli_context_t *cli, int width, int height) { FILE *fp = cli->output_fp; // Write packet type (0xEF) uint8_t packet_type = TAV_PACKET_EXTENDED_HDR; if (fwrite(&packet_type, 1, 1, fp) != 1) return -1; - // Count key-value pairs: BGNT, ENDT, CDAT, VNDR, and optionally FMPG - uint16_t num_pairs = cli->ffmpeg_version ? 5 : 4; + // Count key-value pairs: BGNT, ENDT, CDAT, VNDR, optionally FMPG, and optionally XDIM + int has_xdim = (width > 65535 || height > 65535); + uint16_t num_pairs = 4; // BGNT, ENDT, CDAT, VNDR + if (cli->ffmpeg_version) num_pairs++; // FMPG + if (has_xdim) num_pairs++; // XDIM if (fwrite(&num_pairs, sizeof(uint16_t), 1, fp) != 1) return -1; // Helper macros for writing key-value pairs @@ -578,6 +583,13 @@ static long write_extended_header(cli_context_t *cli) { WRITE_KV_BYTES("FMPG", cli->ffmpeg_version, strlen(cli->ffmpeg_version)); } + // XDIM: Extended dimensions (if width or height exceeds 65535) + if (has_xdim) { + char xdim_str[32]; + snprintf(xdim_str, sizeof(xdim_str), "%d,%d", width, height); + WRITE_KV_BYTES("XDIM", xdim_str, strlen(xdim_str)); + } + #undef WRITE_KV_UINT64 #undef WRITE_KV_BYTES @@ -1460,7 +1472,7 @@ static int encode_video_mt(cli_context_t *cli) { // Write Extended Header (unless suppressed) if (!cli->suppress_xhdr) { - cli->extended_header_offset = write_extended_header(cli); + cli->extended_header_offset = write_extended_header(cli, cli->enc_params.width, cli->enc_params.height); if (cli->extended_header_offset < 0) { fprintf(stderr, "Warning: Failed to write Extended Header\n"); } @@ -1917,7 +1929,7 @@ static int encode_video(cli_context_t *cli) { // Write Extended Header (unless suppressed) if (!cli->suppress_xhdr) { - cli->extended_header_offset = write_extended_header(cli); + cli->extended_header_offset = write_extended_header(cli, cli->enc_params.width, cli->enc_params.height); if (cli->extended_header_offset < 0) { fprintf(stderr, "Warning: Failed to write Extended Header\n"); }