35typedef struct API_AVAILABLE(macos(10.11),
ios(8.0)) YADIFVTContext {
38 AVBufferRef *device_ref;
39 AVBufferRef *input_frames_ref;
40 AVHWFramesContext *input_frames;
49 CVMetalTextureCacheRef textureCache;
50} YADIFVTContext API_AVAILABLE(macos(10.11),
ios(8.0));
55#define YADIF_VT_CTX_SIZE (sizeof(YADIFContext) + sizeof(void*) * 10)
57struct mtlYadifParams {
62 bool skip_spatial_check;
73 int tff) API_AVAILABLE(macos(10.11),
ios(8.0))
75 YADIFVTContext *
s =
ctx->priv;
78 struct mtlYadifParams *
params = (
struct mtlYadifParams *)
s->mtlParamsBuffer.contents;
79 *
params = (
struct mtlYadifParams){
83 .is_second_field = !(
parity ^ tff),
84 .skip_spatial_check =
s->yadif.mode&2,
85 .field_mode =
s->yadif.current_field
88 [encoder setTexture:dst atIndex:0];
89 [encoder setTexture:prev atIndex:1];
90 [encoder setTexture:cur atIndex:2];
91 [encoder setTexture:next atIndex:3];
92 [encoder setBuffer:s->mtlParamsBuffer offset:0 atIndex:4];
94 [encoder endEncoding];
97 [buffer waitUntilCompleted];
104 int parity,
int tff) API_AVAILABLE(macos(10.11),
ios(8.0))
106 YADIFVTContext *
s =
ctx->priv;
113 CVMetalTextureRef prev, cur, next, dest;
117 if (
comp->plane <
i) {
123 pixel_size = (
comp->depth +
comp->shift) / 8;
129 switch (pixel_size) {
131 format =
channels == 1 ? MTLPixelFormatR8Unorm : MTLPixelFormatRG8Unorm;
134 format =
channels == 1 ? MTLPixelFormatR16Unorm : MTLPixelFormatRG16Unorm;
141 "Deinterlacing plane %d: pixel_size: %d channels: %d\n",
149 tex_prev = CVMetalTextureGetTexture(prev);
150 tex_cur = CVMetalTextureGetTexture(cur);
151 tex_next = CVMetalTextureGetTexture(next);
152 tex_dest = CVMetalTextureGetTexture(dest);
163 CVBufferPropagateAttachments((CVPixelBufferRef)y->
cur->
data[3], (CVPixelBufferRef)
dst->data[3]);
175 YADIFVTContext *
s =
ctx->priv;
181 s->input_frames =
NULL;
190 if (
s->textureCache) {
191 CFRelease(
s->textureCache);
192 s->textureCache =
NULL;
199 if (@available(macOS 10.11, iOS 8.0, *)) {
206 YADIFVTContext *
s =
ctx->priv;
210 s->mtlDevice = MTLCreateSystemDefaultDevice();
218 dispatch_data_t libData = dispatch_data_create(
223 s->mtlLibrary = [s->mtlDevice newLibraryWithData:libData error:&err];
224 dispatch_release(libData);
231 s->mtlFunction = [s->mtlLibrary newFunctionWithName:@"deint"];
232 if (!
s->mtlFunction) {
237 s->mtlQueue =
s->mtlDevice.newCommandQueue;
243 s->mtlPipeline = [s->mtlDevice
244 newComputePipelineStateWithFunction:s->mtlFunction
247 av_log(
ctx,
AV_LOG_ERROR,
"Failed to create Metal compute pipeline: %s\n", err.description.UTF8String);
251 s->mtlParamsBuffer = [s->mtlDevice
252 newBufferWithLength:sizeof(struct mtlYadifParams)
253 options:MTLResourceStorageModeShared];
254 if (!
s->mtlParamsBuffer) {
259 ret = CVMetalTextureCacheCreate(
266 if (ret != kCVReturnSuccess) {
273 yadif_videotoolbox_uninit(
ctx);
279 if (@available(macOS 10.11, iOS 8.0, *)) {
281 static_assert(
YADIF_VT_CTX_SIZE ==
sizeof(YADIFVTContext),
"Incorrect YADIF_VT_CTX_SIZE value!");
289static int do_config_input(
AVFilterLink *inlink) API_AVAILABLE(macos(10.11),
ios(8.0))
293 YADIFVTContext *
s =
ctx->priv;
297 "required to associate the processing device.\n");
302 if (!
s->input_frames_ref) {
315 if (@available(macOS 10.11, iOS 8.0, *)) {
316 return do_config_input(inlink);
323static int do_config_output(
AVFilterLink *link) API_AVAILABLE(macos(10.11),
ios(8.0))
329 YADIFVTContext *
s =
ctx->priv;
335 if (!
s->device_ref) {
353 output_frames->
sw_format =
s->input_frames->sw_format;
354 output_frames->
width =
ctx->inputs[0]->w;
355 output_frames->
height =
ctx->inputs[0]->h;
365 "context for output: %d\n", ret);
383 if (@available(macOS 10.11, iOS 8.0, *)) {
384 return do_config_output(link);
391#define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
392#define CONST(name, help, val, unit) { name, help, 0, AV_OPT_TYPE_CONST, {.i64=val}, INT_MIN, INT_MAX, FLAGS, unit }
394static const AVOption yadif_videotoolbox_options[] = {
395 #define OFFSET(x) offsetof(YADIFContext, x)
417static const AVFilterPad yadif_videotoolbox_inputs[] = {
426static const AVFilterPad yadif_videotoolbox_outputs[] = {
436 .p.name =
"yadif_videotoolbox",
438 .p.priv_class = &yadif_videotoolbox_class,
441 .init = yadif_videotoolbox_init,
442 .uninit = yadif_videotoolbox_uninit,
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
SwsAArch64OpImplParams params
static int config_input(AVFilterLink *inlink)
static const char *const format[]
const FFFilter ff_vf_yadif_videotoolbox
static AVFormatContext * ctx
simple assert() macros that are a bit more flexible than ISO C assert().
#define av_assert0(cond)
assert() equivalent, that is always enabled.
int ff_filter_init_hw_frames(AVFilterContext *avctx, AVFilterLink *link, int default_pool_size)
Perform any additional setup required for hardware frames.
#define i(width, name, range_min, range_max)
static void comp(unsigned char *dst, ptrdiff_t dst_stride, unsigned char *src, ptrdiff_t src_stride, int add)
@ AV_OPT_TYPE_INT
Underlying C type is int.
#define AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL
Same as AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC, except that the filter will have its filter_frame() c...
void av_buffer_unref(AVBufferRef **buf)
Free a given reference and automatically free the buffer if there are no more references to it.
AVBufferRef * av_buffer_ref(const AVBufferRef *buf)
Create a new reference to an AVBuffer.
#define AVERROR_EXTERNAL
Generic error in an external library.
#define AV_LOG_TRACE
Extremely verbose debugging, useful for libav* development.
#define AV_LOG_INFO
Standard information.
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
int av_hwframe_ctx_init(AVBufferRef *ref)
Finalize the context before use.
AVBufferRef * av_hwframe_ctx_alloc(AVBufferRef *device_ref_in)
Allocate an AVHWFramesContext tied to a given device context.
An API-specific header for AV_HWDEVICE_TYPE_VIDEOTOOLBOX.
static int config_output(AVBitStreamFilterLink *outlink)
#define FILTER_INPUTS(array)
#define FILTER_OUTPUTS(array)
#define FF_FILTER_FLAG_HWFRAME_AWARE
The filter is aware of hardware frames, and any hardware frame context should not be automatically pr...
static FilterLink * ff_filter_link(AVFilterLink *link)
#define FILTER_SINGLE_PIXFMT(pix_fmt_)
#define AVFILTER_DEFINE_CLASS(fname)
#define CONST(name, help, val, u)
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
static void ff_objc_release(NSObject **obj)
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
@ AV_PIX_FMT_VIDEOTOOLBOX
hardware decoding through Videotoolbox
uint8_t * data
The data buffer.
A link between two filters.
AVFilterContext * src
source filter
AVFilterContext * dst
dest filter
A filter pad used for either input or output.
This structure describes decoded (raw) audio or video data.
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
This struct describes a set or pool of "hardware" frames (i.e.
enum AVPixelFormat format
The pixel format identifying the underlying HW surface type.
void * hwctx
The format-specific data, allocated and freed automatically along with this context.
enum AVPixelFormat sw_format
The pixel format identifying the actual data layout of the hardware frames.
int width
The allocated dimensions of the frames in this pool.
AVComponentDescriptor comp[4]
Parameters that describe how pixels are packed.
uint8_t nb_components
The number of components each pixel has, (1-4)
Link properties exposed to filter code, but not external callers.
AVBufferRef * hw_frames_ctx
For hwaccel pixel formats, this should be a reference to the AVHWFramesContext describing the frames.
void(* filter)(AVFilterContext *ctx, AVFrame *dstpic, int parity, int tff)
int current_field
YADIFCurrentField.
const AVPixFmtDescriptor * csp
void(* filter)(uint8_t *src, ptrdiff_t stride, int qscale)
static CUresult call_kernel(AVFilterContext *ctx, CUfunction func, CUdeviceptr prev, CUdeviceptr cur, CUdeviceptr next, CUarray_format format, int channels, int src_width, int src_height, int src_pitch, CUdeviceptr dst, int dst_width, int dst_height, int dst_pitch, int parity, int tff, int clip_max)
@ YADIF_DEINT_INTERLACED
only deinterlace frames marked as interlaced
@ YADIF_DEINT_ALL
deinterlace all frames
@ YADIF_PARITY_TFF
top field first
@ YADIF_PARITY_BFF
bottom field first
@ YADIF_PARITY_AUTO
auto detection
@ YADIF_FIELD_NORMAL
A normal field in the middle of a sequence.
@ YADIF_FIELD_END
The first or last field in a sequence.
int ff_yadif_filter_frame(AVFilterLink *link, AVFrame *frame)
@ YADIF_MODE_SEND_FIELD_NOSPATIAL
send 1 frame for each field but skips spatial interlacing check
@ YADIF_MODE_SEND_FIELD
send 1 frame for each field
@ YADIF_MODE_SEND_FRAME_NOSPATIAL
send 1 frame for each frame but skips spatial interlacing check
@ YADIF_MODE_SEND_FRAME
send 1 frame for each frame
int ff_yadif_request_frame(AVFilterLink *link)
void ff_yadif_uninit(AVFilterContext *ctx)
int ff_yadif_config_output_common(AVFilterLink *outlink)