libvdo
vdo-example-blocking.cc
#include <vdo-error.h>
#include <vdo-stream.h>
#include <vdo-channel.h>
#include <cerrno>
#include <cstdio>
#include <cstdint>
#include <cstdlib>
#include <poll.h>
#include <unistd.h>
#include <print>
#include <chrono>
#include <utility>
static bool
example_detect_resolution(VdoStream* stream, GError** error)
{
g_autoptr(VdoMap) info = vdo_stream_get_info(stream, error);
if (!info)
return false;
// 'info' includes global-rotation.
auto w = vdo_map_get_uint32(info, "width", 0u);
auto h = vdo_map_get_uint32(info, "height", 0u);
std::println("<6>Resolution: {}x{}", w, h);
return true;
}
int main()
try
{
g_autoptr(GError) error = nullptr;
auto failed = [&error] {
// POSIX error
if (!error) {
std::println(stderr, "<3>error: {}", strerror(errno));
return EXIT_FAILURE;
}
// Maintenance/Installation in progress (e.g. Global-Rotation)
if (vdo_error_is_expected(&error)) {
std::println(stderr, "<6>info: {}", error->message);
return EXIT_SUCCESS;
} else {
std::println(stderr, "<3>error: {}", error->message);
return EXIT_FAILURE;
}
};
g_autoptr(VdoMap) settings = vdo_map_new();
// Stream from the first channel and use its default settings.
vdo_map_set_uint32(settings, "channel", 1u);
vdo_map_set_uint32(settings, "format", VDO_FORMAT_H264);
g_autoptr(VdoStream) stream = vdo_stream_new(settings, nullptr, &error);
if (!stream)
return failed();
if (!example_detect_resolution(stream, &error))
return failed();
if (!vdo_stream_start(stream, &error))
return failed();
// Fetch 10 frames
for (size_t i = 0zu; i < 10zu;) {
g_autoptr(VdoBuffer) buffer = vdo_stream_get_buffer(stream, &error);
if (!buffer && g_error_matches(error, VDO_ERROR, VDO_ERROR_NO_DATA))
continue; // Transient Error -> Retry!
if (!buffer)
return failed();
VdoFrame* frame = vdo_buffer_get_frame(buffer);
// Low jitter monotonic capture timestamp. (See g_get_monotonic_time())
auto pts = vdo_frame_get_timestamp(frame);
auto pts_us = std::chrono::microseconds(pts);
std::println("{:%T}", pts_us);
// Allow VDO to reuse the frame/buffer.
if (!vdo_stream_buffer_unref(stream, &buffer, &error))
return failed();
// Only successful frames count!
i += 1;
}
return EXIT_SUCCESS;
}
catch(const std::exception& e)
{
std::ignore = fprintf(stderr, "Exception: %s\n", e.what());
return EXIT_FAILURE;
}
A video frame.
A class representing a dictionary mapping keys to values.
A video stream.
VdoFrame * vdo_buffer_get_frame(VdoBuffer *self)
Return a pointer to the underlying frame.
A class representing a channel.
Definitions related to error reporting, e.g. error codes.
@ VDO_ERROR_NO_DATA
Definition: vdo-error.h:37
#define VDO_ERROR
Vdo error domain.
Definition: vdo-error.h:19
gboolean vdo_error_is_expected(GError **error)
Check if error is expected.
guint64 vdo_frame_get_timestamp(VdoFrame *self)
Return the capture timestamp of this frame.
guint32 vdo_map_get_uint32(const VdoMap *self, const gchar *name, guint32 def)
Returns the value which the key name is associated with.
VdoMap * vdo_map_new(void)
Constructs an new empty VdoMap.
void vdo_map_set_uint32(VdoMap *self, const gchar *name, guint32 value)
Sets the value associated with the specified key.
A class representing a stream session.
VdoBuffer * vdo_stream_get_buffer(VdoStream *self, GError **error)
Fetch a VdoBuffer containing a frame.
VdoStream * vdo_stream_new(VdoMap *settings, VdoBufferFinalizer fin, GError **error)
Create a new VdoStream.
gboolean vdo_stream_start(VdoStream *self, GError **error)
Start this video stream.
gboolean vdo_stream_buffer_unref(VdoStream *self, VdoBuffer **buffer, GError **error)
Decrease the reference count for the specified buffer.
VdoMap * vdo_stream_get_info(VdoStream *self, GError **error)
Get the info for this video stream.
@ VDO_FORMAT_H264
Definition: vdo-types.h:51