diff options
Diffstat (limited to 'filters/f_utils.h')
-rw-r--r-- | filters/f_utils.h | 72 |
1 files changed, 72 insertions, 0 deletions
diff --git a/filters/f_utils.h b/filters/f_utils.h new file mode 100644 index 0000000000..a59ac1601d --- /dev/null +++ b/filters/f_utils.h @@ -0,0 +1,72 @@ +#pragma once + +#include "filter.h" + +// Filter that computes the exact duration of video frames by buffering 1 frame, +// and taking the PTS difference. This supports video frames only, and stores +// the duration in mp_image.pkt_duration. All other frame types are passed +// through. +struct mp_filter *mp_compute_frame_duration_create(struct mp_filter *parent); + +// Given the filters[0..num_filters] array, connect in with the input of the +// first filter, connect the output of the first filter to the input to the +// second filter, etc., until out. All filters are assumed to be bidrectional, +// with input on pin 0 and output on pin 1. NULL entries are skipped. +void mp_chain_filters(struct mp_pin *in, struct mp_pin *out, + struct mp_filter **filters, int num_filters); + +// Helper for maintaining a sub-filter that is created or destroyed on demand, +// because it might depend on frame input formats or is otherwise dynamically +// changing. (This is overkill for more static sub filters, or entirely manual +// filtering.) +// To initialize this, zero-init all fields, and set the in/out fields. +struct mp_subfilter { + // These two fields must be set on init. The pins must have a manual + // connection to the filter whose process() function calls the + // mp_subfilter_*() functions. + struct mp_pin *in, *out; + // Temporary buffered frame, as triggered by mp_subfilter_read(). You can + // not mutate this (unless you didn't create or destroy sub->filter). + struct mp_frame frame; + // The sub-filter, set by the user. Can be NULL if disabled. If set, this + // must be a bidirectional filter, with manual connections same as + // mp_sub_filter.in/out (to get the correct process() function called). + // Set this only if it's NULL. You should not overwrite this if it's set. + // Use either mp_subfilter_drain_destroy(), mp_subfilter_destroy(), or + // mp_subfilter_reset() to unset and destroy the filter gracefully. + struct mp_filter *filter; + // Internal state. + bool draining; +}; + +// Make requests for a new frame. +// Returns whether sub->frame is set to anything. If true is returned, you +// must either call mp_subfilter_continue() or mp_subfilter_drain_destroy() +// once to continue data flow normally (otherwise it will stall). If you call +// mp_subfilter_drain_destroy(), and it returns true, or you call +// mp_subfilter_destroy(), you can call mp_subfilter_continue() once after it. +// If this returns true, sub->frame is never unset (MP_FRAME_NONE). +bool mp_subfilter_read(struct mp_subfilter *sub); + +// Clear internal state (usually to be called by parent filter's reset(), or +// destroy()). This usually does not free sub->filter. +void mp_subfilter_reset(struct mp_subfilter *sub); + +// Continue filtering sub->frame. This can happen after setting a new filter +// too. +void mp_subfilter_continue(struct mp_subfilter *sub); + +// Destroy the filter immediately (if it's set). You must call +// mp_subfilter_continue() after this to propagate sub->frame. +void mp_subfilter_destroy(struct mp_subfilter *sub); + +// Make sure the filter is destroyed. Returns true if the filter was destroyed. +// If this returns false, exit your process() function, so dataflow can +// continue normally. (process() is repeated until this function returns true, +// which can take a while if sub->filter has many frames buffered). +// If this returns true, call mp_subfilter_continue() to propagate sub->frame. +// The filter is destroyed with talloc_free(sub->filter). +bool mp_subfilter_drain_destroy(struct mp_subfilter *sub); + +// A bidrectional filter which passes through all data. +struct mp_filter *mp_bidir_nop_filter_create(struct mp_filter *parent); |