mirror of
https://github.com/curioustorvald/tsvm.git
synced 2026-03-07 11:51:49 +09:00
tavenc: header support for extended dimensions (max(width,height) > 65535)
This commit is contained in:
@@ -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.
|
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 Width: picture width in pixels. Columns count for Videotex-only file.
|
||||||
uint16 Height: picture height in pixels. Rows 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
|
uint8 FPS: frames per second. Use 0x00 for still pictures
|
||||||
uint32 Total Frames: number of video frames
|
uint32 Total Frames: number of video frames
|
||||||
- use 0 to denote not-finalised video stream
|
- use 0 to denote not-finalised video stream
|
||||||
@@ -1091,8 +1092,9 @@ The encoder supports following presets:
|
|||||||
<if Value Type is Bytes>
|
<if Value Type is Bytes>
|
||||||
uint16 Length of bytes
|
uint16 Length of bytes
|
||||||
* Bytes
|
* Bytes
|
||||||
<otherwise>
|
<else>
|
||||||
type_t Value
|
type_t Value
|
||||||
|
<fi>
|
||||||
|
|
||||||
### List of Keys
|
### List of Keys
|
||||||
- Uint64 BGNT: Video begin time in nanoseconds (must be equal to the value of the first Timecode packet)
|
- 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)
|
- 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 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 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 '<width>,<height>' format. Mandatory if either width or height exceeds 65535
|
||||||
|
|
||||||
## Extensible Packet Structure
|
## Extensible Packet Structure
|
||||||
uint8 Packet Type
|
uint8 Packet Type
|
||||||
@@ -1108,8 +1111,9 @@ The encoder supports following presets:
|
|||||||
uint8 Identifier[4]
|
uint8 Identifier[4]
|
||||||
<if 64-bit size>
|
<if 64-bit size>
|
||||||
uint64 Length of the payload
|
uint64 Length of the payload
|
||||||
<if not>
|
<else>
|
||||||
uint32 Length of the payload
|
uint32 Length of the payload
|
||||||
|
<fi>
|
||||||
* Payload
|
* Payload
|
||||||
|
|
||||||
## Standard Metadata Payload Packet Structure
|
## Standard Metadata Payload Packet Structure
|
||||||
@@ -1178,7 +1182,7 @@ temporal compression.
|
|||||||
<if packet type is 0x13>
|
<if packet type is 0x13>
|
||||||
uint32 Compressed Size
|
uint32 Compressed Size
|
||||||
* Zstd-compressed Motion Data
|
* Zstd-compressed Motion Data
|
||||||
<endif>
|
<fi>
|
||||||
uint32 Compressed Size
|
uint32 Compressed Size
|
||||||
* Zstd-compressed Unified Block Data
|
* 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 Y Non-zero Values[variable length] // All Y non-zero coefficients
|
||||||
int16 Co Non-zero Values[variable length] // All Co 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
|
int16 Cg Non-zero Values[variable length] // All Cg non-zero coefficients
|
||||||
|
<fi>
|
||||||
|
|
||||||
<if EZBC is used>
|
<if EZBC is used>
|
||||||
uint32 EZBC Size for Y
|
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
|
* EZBC Structure for Co
|
||||||
uint32 EZBC Size for Cg
|
uint32 EZBC Size for Cg
|
||||||
* EZBC Structure for Cg
|
* EZBC Structure for Cg
|
||||||
|
<fi>
|
||||||
|
|
||||||
This layout enables Zstd to find patterns across both spatial and temporal dimensions,
|
This layout enables Zstd to find patterns across both spatial and temporal dimensions,
|
||||||
resulting in superior compression compared to per-frame encoding.
|
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
|
|||||||
<if external addressing mode>
|
<if external addressing mode>
|
||||||
uint16 String Length for relative path
|
uint16 String Length for relative path
|
||||||
* Relative path
|
* Relative path
|
||||||
|
<fi>
|
||||||
|
|
||||||
<if internal addressing mode>
|
<if internal addressing mode>
|
||||||
uint48 Offset to the file
|
uint48 Offset to the file
|
||||||
|
<fi>
|
||||||
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|||||||
@@ -464,11 +464,13 @@ static int write_tav_header(FILE *fp, const tav_encoder_params_t *params, int ha
|
|||||||
fputc(version, fp);
|
fputc(version, fp);
|
||||||
|
|
||||||
// Width (uint16_t, 2 bytes)
|
// 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);
|
fwrite(&width, sizeof(uint16_t), 1, fp);
|
||||||
|
|
||||||
// Height (uint16_t, 2 bytes)
|
// 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);
|
fwrite(&height, sizeof(uint16_t), 1, fp);
|
||||||
|
|
||||||
// FPS (uint8_t, 1 byte) - simplified to just fps_num
|
// 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.
|
* Write Extended Header packet (0xEF) with metadata.
|
||||||
* Returns the file offset of the ENDT value for later update, or -1 on error.
|
* 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;
|
FILE *fp = cli->output_fp;
|
||||||
|
|
||||||
// Write packet type (0xEF)
|
// Write packet type (0xEF)
|
||||||
uint8_t packet_type = TAV_PACKET_EXTENDED_HDR;
|
uint8_t packet_type = TAV_PACKET_EXTENDED_HDR;
|
||||||
if (fwrite(&packet_type, 1, 1, fp) != 1) return -1;
|
if (fwrite(&packet_type, 1, 1, fp) != 1) return -1;
|
||||||
|
|
||||||
// Count key-value pairs: BGNT, ENDT, CDAT, VNDR, and optionally FMPG
|
// Count key-value pairs: BGNT, ENDT, CDAT, VNDR, optionally FMPG, and optionally XDIM
|
||||||
uint16_t num_pairs = cli->ffmpeg_version ? 5 : 4;
|
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;
|
if (fwrite(&num_pairs, sizeof(uint16_t), 1, fp) != 1) return -1;
|
||||||
|
|
||||||
// Helper macros for writing key-value pairs
|
// 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));
|
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_UINT64
|
||||||
#undef WRITE_KV_BYTES
|
#undef WRITE_KV_BYTES
|
||||||
|
|
||||||
@@ -1460,7 +1472,7 @@ static int encode_video_mt(cli_context_t *cli) {
|
|||||||
|
|
||||||
// Write Extended Header (unless suppressed)
|
// Write Extended Header (unless suppressed)
|
||||||
if (!cli->suppress_xhdr) {
|
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) {
|
if (cli->extended_header_offset < 0) {
|
||||||
fprintf(stderr, "Warning: Failed to write Extended Header\n");
|
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)
|
// Write Extended Header (unless suppressed)
|
||||||
if (!cli->suppress_xhdr) {
|
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) {
|
if (cli->extended_header_offset < 0) {
|
||||||
fprintf(stderr, "Warning: Failed to write Extended Header\n");
|
fprintf(stderr, "Warning: Failed to write Extended Header\n");
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user