shared/bpm: Add BPM (Broadcast Performance Metrics)

Introduce support for delivering BPM (Broadcast
Performance Metrics) over SEI (for AVC/H.264 and
HEVC/H.265) and OBU (for AV1) unregistered messages.
Metrics being sent are the session frame counters,
per-rendition frame counters, and RFC3339-based
timestamping information to support end-to-end
latency measurement.

SEI/OBU messages are generated and sent with each IDR
frame, and the frame counters are diff-based, meaning
the counts reflect the diff between IDRs, not the running
totals.

BPM documentation is available at [1].

BPM relies on the recently introduced encoder packet timing
support and the packet callback mechanism.

BPM injection is enabled for an output by registering
the `bpm_inject()` callback via `obs_output_add_packet_callback()`
function. The callback must be unregistered using
`obs_output_remove_packet_callback()` and `bpm_destroy()`
must be used by the caller to release the BPM structures.

It is important to measure the number of frames successfully
encoded by the obs_encoder_t instances, particularly for
renditions where the encoded frame rate differs from the
canvas frame rate. The encoded_frames counter and
`obs_encoder_get_encoded_frames()` API is introduced
to measure and report this in the encoded rendition
metrics message.

[1] https://d50yg09cghihd.cloudfront.net/other/20240718-MultitrackVideoIntegrationGuide.pdf
This commit is contained in:
Alex Luccisano
2024-09-05 16:38:58 -04:00
committed by Ryan Foster
parent 0a36ed1164
commit 07d504e5c7
11 changed files with 870 additions and 15 deletions
+11
View File
@@ -857,6 +857,13 @@ enum obs_encoder_type obs_get_encoder_type(const char *id)
return info ? info->type : OBS_ENCODER_AUDIO;
}
uint32_t obs_encoder_get_encoded_frames(const obs_encoder_t *encoder)
{
return obs_encoder_valid(encoder, "obs_output_get_encoded_frames")
? encoder->encoded_frames
: 0;
}
void obs_encoder_set_scaled_size(obs_encoder_t *encoder, uint32_t width,
uint32_t height)
{
@@ -1393,6 +1400,10 @@ void send_off_encoder_packet(obs_encoder_t *encoder, bool success,
}
pthread_mutex_unlock(&encoder->callbacks_mutex);
// Count number of video frames successfully encoded
if (pkt->type == OBS_ENCODER_VIDEO)
encoder->encoded_frames++;
}
}