Skip to content

Commit e51f042

Browse files
feat: add non-terminal output polling
1 parent 973961c commit e51f042

6 files changed

Lines changed: 58 additions & 7 deletions

File tree

include/fma/client.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ int fma_client_queue_packet(struct fma_client *client, const void *data,
2525
size_t size, int64_t pts_us, uint32_t flags);
2626
int fma_client_drain(struct fma_client *client);
2727
int fma_client_flush(struct fma_client *client);
28+
int fma_client_poll_output(struct fma_client *client, uint32_t timeout_ms);
2829
int fma_client_release_frame(struct fma_client *client, uint32_t slot);
2930
int fma_client_receive(struct fma_client *client, struct fma_message *message);
3031

include/fma/protocol.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ extern "C" {
1010

1111
#define FMA_MAGIC UINT32_C(0x31414d46) /* FMA1 on a little-endian wire. */
1212
#define FMA_PROTOCOL_MAJOR 1u
13-
#define FMA_PROTOCOL_MINOR 0u
13+
#define FMA_PROTOCOL_MINOR 1u
1414
#define FMA_WIRE_HEADER_SIZE 48u
1515
#define FMA_MAX_PAYLOAD (8u * 1024u * 1024u)
1616
#define FMA_MAX_FDS 4u
@@ -37,6 +37,8 @@ enum fma_message_type {
3737
FMA_MSG_OUTPUT_EOS = 15,
3838
FMA_MSG_CLOSE = 16,
3939
FMA_MSG_ERROR = 17,
40+
FMA_MSG_POLL_OUTPUT = 18,
41+
FMA_MSG_POLL_DONE = 19,
4042
};
4143

4244
enum fma_codec {
@@ -61,6 +63,7 @@ enum fma_packet_flags {
6163
enum fma_capability_flags {
6264
FMA_CAP_SHARED_FRAME_POOL = 1u << 0,
6365
FMA_CAP_CAN_FLUSH = 1u << 1,
66+
FMA_CAP_CAN_POLL = 1u << 2,
6467
};
6568

6669
struct fma_message {

src/android/fake-media-acceld.c

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -444,7 +444,8 @@ static int serve_client(int fd) {
444444
struct fma_capabilities caps = {
445445
.decoder_mask = probe_decoders(),
446446
.pixel_format_mask = 1u << (FMA_PIXFMT_NV12 - 1u),
447-
.flags = FMA_CAP_SHARED_FRAME_POOL | FMA_CAP_CAN_FLUSH,
447+
.flags = FMA_CAP_SHARED_FRAME_POOL | FMA_CAP_CAN_FLUSH |
448+
FMA_CAP_CAN_POLL,
448449
.max_width = 0,
449450
.max_height = 0,
450451
};
@@ -520,6 +521,23 @@ static int serve_client(int fd) {
520521
}
521522
}
522523
break;
524+
case FMA_MSG_POLL_OUTPUT: {
525+
if (!session.started || request.payload_size != 4) {
526+
result = send_error(fd, &request, "invalid output poll");
527+
break;
528+
}
529+
uint32_t timeout_ms = fma_get_u32(request.payload);
530+
if (timeout_ms > 1000)
531+
timeout_ms = 1000;
532+
int output = emit_output(fd, &request, &session,
533+
(int64_t)timeout_ms * 1000, false);
534+
if (output < 0)
535+
result = send_error(fd, &request, "MediaCodec output poll failed");
536+
else
537+
result = send_reply(fd, &request, FMA_MSG_POLL_DONE, NULL, 0,
538+
session.id, -1);
539+
break;
540+
}
523541
case FMA_MSG_CLOSE:
524542
fma_message_release(&request);
525543
destroy_decoder(&session);

src/client/client.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,13 @@ int fma_client_flush(struct fma_client *client) {
142142
return 0;
143143
}
144144

145+
int fma_client_poll_output(struct fma_client *client, uint32_t timeout_ms) {
146+
uint8_t payload[4];
147+
fma_put_u32(payload, timeout_ms);
148+
return send_simple(client, FMA_MSG_POLL_OUTPUT, payload, sizeof(payload),
149+
0, 0, NULL);
150+
}
151+
145152
int fma_client_release_frame(struct fma_client *client, uint32_t slot) {
146153
uint8_t payload[4];
147154
fma_put_u32(payload, slot);

src/fake/fake-media-acceld.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ struct fake_session {
2121
uint8_t *pool_map;
2222
size_t pool_bytes;
2323
uint32_t next_slot;
24-
bool slots[16];
24+
bool slots[FMA_MAX_SLOTS];
2525
};
2626

2727
static volatile sig_atomic_t running = 1;
@@ -177,7 +177,8 @@ static int handle_client(int fd) {
177177
FMA_CODEC_BIT(FMA_CODEC_VP9) |
178178
FMA_CODEC_BIT(FMA_CODEC_AV1),
179179
.pixel_format_mask = 1u << (FMA_PIXFMT_NV12 - 1u),
180-
.flags = FMA_CAP_SHARED_FRAME_POOL | FMA_CAP_CAN_FLUSH,
180+
.flags = FMA_CAP_SHARED_FRAME_POOL | FMA_CAP_CAN_FLUSH |
181+
FMA_CAP_CAN_POLL,
181182
.max_width = 8192,
182183
.max_height = 8192,
183184
};
@@ -228,6 +229,13 @@ static int handle_client(int fd) {
228229
result = send_reply(fd, &request, FMA_MSG_OUTPUT_EOS, NULL, 0,
229230
session.id, -1);
230231
break;
232+
case FMA_MSG_POLL_OUTPUT:
233+
if (request.payload_size != 4)
234+
result = send_error(fd, &request, "invalid poll request");
235+
else
236+
result = send_reply(fd, &request, FMA_MSG_POLL_DONE, NULL, 0,
237+
session.id, -1);
238+
break;
231239
case FMA_MSG_CLOSE:
232240
fma_message_release(&request);
233241
destroy_pool(&session);

tools/fma-decode.c

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ static uint32_t parse_codec(const char *name) {
115115
static int process_message(struct fma_client *client,
116116
const struct fma_frame_pool *pool, uint8_t *pool_map,
117117
FILE *output, uint64_t *frames, bool *packet_ack,
118-
bool *eos) {
118+
bool *eos, bool *poll_done) {
119119
struct fma_message message;
120120
if (fma_client_receive(client, &message) < 0)
121121
return -1;
@@ -140,6 +140,8 @@ static int process_message(struct fma_client *client,
140140
*packet_ack = true;
141141
} else if (message.type == FMA_MSG_OUTPUT_EOS) {
142142
*eos = true;
143+
} else if (message.type == FMA_MSG_POLL_DONE) {
144+
*poll_done = true;
143145
} else if (message.type == FMA_MSG_ERROR) {
144146
fprintf(stderr, "daemon: %.*s\n", (int)message.payload_size,
145147
message.payload ? (char *)message.payload : "error");
@@ -242,6 +244,7 @@ int main(int argc, char **argv) {
242244
for (size_t i = 0; i < unit_count; ++i) {
243245
int64_t pts_us = (int64_t)(i * UINT64_C(1000000) / fps);
244246
bool packet_ack = false;
247+
bool poll_done = false;
245248
if (fma_client_queue_packet(&client, input + units[i].offset,
246249
units[i].size, pts_us, 0) < 0) {
247250
perror("decode");
@@ -251,17 +254,28 @@ int main(int argc, char **argv) {
251254
input_bytes += units[i].size;
252255
while (!packet_ack &&
253256
process_message(&client, &pool, pool_map, output, &frames,
254-
&packet_ack, &eos) == 0) {}
257+
&packet_ack, &eos, &poll_done) == 0) {}
255258
if (!packet_ack) {
256259
perror("decode");
257260
failed = true;
258261
break;
259262
}
260263
}
264+
if (!failed && fma_client_poll_output(&client, 0) == 0) {
265+
bool packet_ack = false;
266+
bool poll_done = false;
267+
while (!poll_done &&
268+
process_message(&client, &pool, pool_map, output, &frames,
269+
&packet_ack, &eos, &poll_done) == 0) {}
270+
if (!poll_done)
271+
failed = true;
272+
}
261273
if (!failed && fma_client_drain(&client) == 0) {
262274
bool packet_ack = false;
275+
bool poll_done = false;
263276
while (!eos && process_message(&client, &pool, pool_map, output,
264-
&frames, &packet_ack, &eos) == 0) {}
277+
&frames, &packet_ack, &eos,
278+
&poll_done) == 0) {}
265279
}
266280
if (!eos)
267281
failed = true;

0 commit comments

Comments
 (0)