ascii-chat 0.11.33
Video chat in your terminal
Loading...
Searching...
No Matches
server.h File Reference

Server-side H.265 decoding pipeline for multi-client streams. More...

Go to the source code of this file.

Typedefs

typedef struct h265_server_context h265_server_context_t
 
typedef struct h265_server_client h265_server_client_t
 

Functions

h265_server_context_t * h265_server_context_create (void)
 
void h265_server_context_destroy (h265_server_context_t *ctx)
 
h265_server_client_t * h265_server_get_client_decoder (h265_server_context_t *ctx, uint32_t client_id)
 
asciichat_error_t h265_server_decode_and_convert (h265_server_client_t *client, const uint8_t *h265_packet, size_t packet_size, uint8_t *output_rgba, uint16_t *output_width, uint16_t *output_height, size_t *output_size)
 
void h265_server_remove_client (h265_server_context_t *ctx, uint32_t client_id)
 
void h265_server_client_get_stats (h265_server_client_t *client, uint64_t *total_frames, uint64_t *keyframes, uint16_t *last_width, uint16_t *last_height)
 

Detailed Description

Server-side H.265 decoding pipeline for multi-client streams.

The server maintains a separate H.265 decoder for each connected client. When a client sends an H.265-encoded frame, the server:

  1. Identifies the decoder for that client
  2. Decodes the H.265 frame to ASCII art
  3. Converts ASCII art to RGBA pixels for compositing
  4. Adds the RGBA frame to the compositing pipeline

Definition in file src/session/h265/server.h.

Typedef Documentation

◆ h265_server_client_t

typedef struct h265_server_client h265_server_client_t

Definition at line 20 of file src/session/h265/server.h.

◆ h265_server_context_t

Definition at line 19 of file src/session/h265/server.h.

Function Documentation

◆ h265_server_client_get_stats()

void h265_server_client_get_stats ( h265_server_client_t *  client,
uint64_t *  total_frames,
uint64_t *  keyframes,
uint16_t *  last_width,
uint16_t *  last_height 
)

Get statistics for a client's decoder

Parameters
clientClient decoder
total_framesOutput: total frames decoded
keyframesOutput: total keyframes decoded
last_widthOutput: width of last decoded frame
last_heightOutput: height of last decoded frame

Definition at line 153 of file src/session/h265/server.c.

154 {
155 if (!client)
156 return;
157
158 h265_client_decoder_t *client_dec = (h265_client_decoder_t *)client;
159 if (!client_dec->decoder)
160 return;
161
162 h265_decoder_get_stats(client_dec->decoder, total_frames, keyframes, last_width, last_height);
163}
void h265_decoder_get_stats(h265_decoder_t *decoder, uint64_t *total_frames, uint64_t *keyframes, uint16_t *last_width, uint16_t *last_height)
Definition decoder.c:187

References h265_client_decoder_t::decoder, and h265_decoder_get_stats().

◆ h265_server_context_create()

h265_server_context_t * h265_server_context_create ( void  )

Create a server-side H.265 decoding context Manages decoders for all connected clients

Returns
Context handle, or NULL on error

Definition at line 27 of file src/session/h265/server.c.

27 {
29 if (!ctx) {
30 SET_ERRNO(ERROR_MEMORY, "Failed to allocate server context");
31 return NULL;
32 }
33
34 for (int i = 0; i < MAX_CLIENTS; i++) {
35 ctx->clients[i].in_use = false;
36 }
37 ctx->active_client_count = 0;
38
39 log_info("H.265 server context created (max %d clients)", MAX_CLIENTS);
40 return ctx;
41}
#define SAFE_CALLOC(count, size, cast)
Definition common.h:274
#define SET_ERRNO(code, context_msg,...)
Set error code with custom context message and log it, returning the error code.
@ ERROR_MEMORY
Definition error_codes.h:56
#define MAX_CLIENTS
Maximum possible clients (static array size) - actual runtime limit set by –max-clients (1-32)
Definition limits.h:26
#define log_info(...)
Log an INFO message.
Definition log/log.h:561
h265_client_decoder_t clients[MAX_CLIENTS]

References h265_server_context::active_client_count, h265_server_context::clients, ERROR_MEMORY, h265_client_decoder_t::in_use, log_info, MAX_CLIENTS, SAFE_CALLOC, and SET_ERRNO.

◆ h265_server_context_destroy()

void h265_server_context_destroy ( h265_server_context_t *  ctx)

Destroy the server context and all client decoders

Parameters
ctxContext to destroy (may be NULL)

Definition at line 43 of file src/session/h265/server.c.

43 {
44 if (!ctx)
45 return;
46
47 for (int i = 0; i < MAX_CLIENTS; i++) {
48 if (ctx->clients[i].in_use && ctx->clients[i].decoder) {
50 }
51 }
52 SAFE_FREE(ctx);
53}
void h265_decoder_destroy(h265_decoder_t *decoder)
Definition decoder.c:90
#define SAFE_FREE(ptr)
Definition common.h:376

References h265_server_context::clients, h265_client_decoder_t::decoder, h265_decoder_destroy(), h265_client_decoder_t::in_use, MAX_CLIENTS, and SAFE_FREE.

◆ h265_server_decode_and_convert()

asciichat_error_t h265_server_decode_and_convert ( h265_server_client_t *  client,
const uint8_t *  h265_packet,
size_t  packet_size,
uint8_t *  output_rgba,
uint16_t *  output_width,
uint16_t *  output_height,
size_t *  output_size 
)

Decode an H.265 frame from a client and convert to RGBA

Parameters
clientClient decoder handle
h265_packetH.265 encoded packet data (with header)
packet_sizeSize of packet
output_rgbaOutput buffer for RGBA pixel data
output_widthOutput: frame width in pixels
output_heightOutput: frame height in pixels
output_sizeInput: buffer size, Output: actual RGBA size (width*height*4)
Returns
Error code (ASCIICHAT_OK on success)

RGBA conversion: Each ASCII character (0-255) becomes a grayscale pixel where pixel = (ascii_val, ascii_val, ascii_val, 255)

Definition at line 91 of file src/session/h265/server.c.

93 {
94 if (!client || !h265_packet || !output_rgba || !output_width || !output_height || !output_size) {
95 return SET_ERRNO(ERROR_INTERNAL, "Invalid arguments to decode_and_convert");
96 }
97
98 h265_client_decoder_t *client_dec = (h265_client_decoder_t *)client;
99 if (!client_dec->decoder || !client_dec->in_use) {
100 return SET_ERRNO(ERROR_INTERNAL, "Invalid client decoder state");
101 }
102
103 uint8_t ascii_buf[256 * 64];
104 size_t ascii_size = sizeof(ascii_buf);
105
106 asciichat_error_t result =
107 h265_decode(client_dec->decoder, h265_packet, packet_size, output_width, output_height, ascii_buf, &ascii_size);
108
109 if (result != ASCIICHAT_OK) {
110 return result;
111 }
112
113 size_t required_rgba_size = (size_t)(*output_width) * (*output_height) * 4;
114 if (*output_size < required_rgba_size) {
115 *output_size = required_rgba_size;
116 return SET_ERRNO(ERROR_NETWORK_SIZE, "Output buffer too small: need %zu, have %zu", required_rgba_size,
117 *output_size);
118 }
119
120 for (size_t i = 0; i < ascii_size && i < (size_t)(*output_width) * (*output_height); i++) {
121 uint8_t val = ascii_buf[i];
122 output_rgba[i * 4 + 0] = val;
123 output_rgba[i * 4 + 1] = val;
124 output_rgba[i * 4 + 2] = val;
125 output_rgba[i * 4 + 3] = 255;
126 }
127
128 *output_size = required_rgba_size;
129 client_dec->last_width = *output_width;
130 client_dec->last_height = *output_height;
131
132 return ASCIICHAT_OK;
133}
asciichat_error_t h265_decode(h265_decoder_t *decoder, const uint8_t *encoded_packet, size_t packet_size, uint16_t *output_width, uint16_t *output_height, uint8_t *output_buf, size_t *output_size)
Definition decoder.c:109
unsigned char uint8_t
Definition common.h:56
asciichat_error_t
Error and exit codes - unified status values (0-255)
Definition error_codes.h:49
@ ASCIICHAT_OK
Definition error_codes.h:51
@ ERROR_NETWORK_SIZE
Definition error_codes.h:82
@ ERROR_INTERNAL
Definition error_codes.h:92

References ASCIICHAT_OK, h265_client_decoder_t::decoder, ERROR_INTERNAL, ERROR_NETWORK_SIZE, h265_decode(), h265_client_decoder_t::in_use, h265_client_decoder_t::last_height, h265_client_decoder_t::last_width, and SET_ERRNO.

Referenced by handle_image_frame_h265_packet().

◆ h265_server_get_client_decoder()

h265_server_client_t * h265_server_get_client_decoder ( h265_server_context_t *  ctx,
uint32_t  client_id 
)

Get or create a client decoder within the server context Each client gets its own H.265 decoder instance

Parameters
ctxServer context
client_idUnique client identifier
Returns
Client decoder handle, or NULL on error

Definition at line 55 of file src/session/h265/server.c.

55 {
56 if (!ctx) {
57 SET_ERRNO(ERROR_INTERNAL, "Invalid server context");
58 return NULL;
59 }
60
61 for (int i = 0; i < MAX_CLIENTS; i++) {
62 if (ctx->clients[i].in_use && ctx->clients[i].client_id == client_id) {
63 return (h265_server_client_t *)&ctx->clients[i];
64 }
65 }
66
67 for (int i = 0; i < MAX_CLIENTS; i++) {
68 if (!ctx->clients[i].in_use) {
70 if (!decoder) {
71 SET_ERRNO(ERROR_MEDIA_INIT, "Failed to create decoder for client %u", client_id);
72 return NULL;
73 }
74
75 ctx->clients[i].client_id = client_id;
76 ctx->clients[i].decoder = decoder;
77 ctx->clients[i].in_use = true;
78 ctx->clients[i].last_width = 0;
79 ctx->clients[i].last_height = 0;
81
82 log_debug("Created H.265 decoder for client %u", client_id);
83 return (h265_server_client_t *)&ctx->clients[i];
84 }
85 }
86
87 SET_ERRNO(ERROR_INTERNAL, "No free decoder slots (max %d clients)", MAX_CLIENTS);
88 return NULL;
89}
h265_decoder_t * h265_decoder_create(void)
Definition decoder.c:31
@ ERROR_MEDIA_INIT
Definition error_codes.h:70
#define log_debug(...)
Log a DEBUG message.
Definition log/log.h:548
struct h265_server_client h265_server_client_t

References h265_server_context::active_client_count, h265_client_decoder_t::client_id, h265_server_context::clients, h265_client_decoder_t::decoder, ERROR_INTERNAL, ERROR_MEDIA_INIT, h265_decoder_create(), h265_client_decoder_t::in_use, h265_client_decoder_t::last_height, h265_client_decoder_t::last_width, log_debug, MAX_CLIENTS, and SET_ERRNO.

Referenced by handle_image_frame_h265_packet().

◆ h265_server_remove_client()

void h265_server_remove_client ( h265_server_context_t *  ctx,
uint32_t  client_id 
)

Remove a client decoder (when client disconnects)

Parameters
ctxServer context
client_idClient identifier

Definition at line 135 of file src/session/h265/server.c.

135 {
136 if (!ctx)
137 return;
138
139 for (int i = 0; i < MAX_CLIENTS; i++) {
140 if (ctx->clients[i].in_use && ctx->clients[i].client_id == client_id) {
141 if (ctx->clients[i].decoder) {
143 ctx->clients[i].decoder = NULL;
144 }
145 ctx->clients[i].in_use = false;
146 ctx->active_client_count--;
147 log_debug("Removed H.265 decoder for client %u", client_id);
148 return;
149 }
150 }
151}

References h265_server_context::active_client_count, h265_client_decoder_t::client_id, h265_server_context::clients, h265_client_decoder_t::decoder, h265_decoder_destroy(), h265_client_decoder_t::in_use, log_debug, and MAX_CLIENTS.