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;
112 CVMetalTextureRef prev, cur, next, dest;
116 if (
comp->plane <
i) {
122 pixel_size = (
comp->depth +
comp->shift) / 8;
128 switch (pixel_size) {
130 format =
channels == 1 ? MTLPixelFormatR8Unorm : MTLPixelFormatRG8Unorm;
133 format =
channels == 1 ? MTLPixelFormatR16Unorm : MTLPixelFormatRG16Unorm;
140 "Deinterlacing plane %d: pixel_size: %d channels: %d\n",
148 if (!prev || !cur || !next || !dest) {
150 if (prev) CFRelease(prev);
151 if (cur) CFRelease(cur);
152 if (next) CFRelease(next);
153 if (dest) CFRelease(dest);
157 tex_prev = CVMetalTextureGetTexture(prev);
158 tex_cur = CVMetalTextureGetTexture(cur);
159 tex_next = CVMetalTextureGetTexture(next);
160 tex_dest = CVMetalTextureGetTexture(dest);
171 CVBufferPropagateAttachments((CVPixelBufferRef)y->
cur->
data[3], (CVPixelBufferRef)
dst->data[3]);
180 YADIFVTContext *
s =
ctx->priv;
186 s->input_frames =
NULL;
195 if (
s->textureCache) {
196 CFRelease(
s->textureCache);
197 s->textureCache =
NULL;
204 if (@available(macOS 10.11, iOS 8.0, *)) {
211 YADIFVTContext *
s =
ctx->priv;
215 s->mtlDevice = MTLCreateSystemDefaultDevice();
223 dispatch_data_t libData = dispatch_data_create(
228 s->mtlLibrary = [s->mtlDevice newLibraryWithData:libData error:&err];
229 dispatch_release(libData);
236 s->mtlFunction = [s->mtlLibrary newFunctionWithName:@"deint"];
237 if (!
s->mtlFunction) {
242 s->mtlQueue =
s->mtlDevice.newCommandQueue;
248 s->mtlPipeline = [s->mtlDevice
249 newComputePipelineStateWithFunction:s->mtlFunction
252 av_log(
ctx,
AV_LOG_ERROR,
"Failed to create Metal compute pipeline: %s\n", err.description.UTF8String);
256 s->mtlParamsBuffer = [s->mtlDevice
257 newBufferWithLength:sizeof(struct mtlYadifParams)
258 options:MTLResourceStorageModeShared];
259 if (!
s->mtlParamsBuffer) {
264 ret = CVMetalTextureCacheCreate(
271 if (ret != kCVReturnSuccess) {
278 yadif_videotoolbox_uninit(
ctx);
284 if (@available(macOS 10.11, iOS 8.0, *)) {
286 static_assert(
YADIF_VT_CTX_SIZE ==
sizeof(YADIFVTContext),
"Incorrect YADIF_VT_CTX_SIZE value!");
294static int do_config_input(
AVFilterLink *inlink) API_AVAILABLE(macos(10.11),
ios(8.0))
298 YADIFVTContext *
s =
ctx->priv;
302 "required to associate the processing device.\n");
307 if (!
s->input_frames_ref) {
320 if (@available(macOS 10.11, iOS 8.0, *)) {
321 return do_config_input(inlink);
328static int do_config_output(
AVFilterLink *link) API_AVAILABLE(macos(10.11),
ios(8.0))
334 YADIFVTContext *
s =
ctx->priv;
340 if (!
s->device_ref) {
358 output_frames->
sw_format =
s->input_frames->sw_format;
359 output_frames->
width =
ctx->inputs[0]->w;
360 output_frames->
height =
ctx->inputs[0]->h;
370 "context for output: %d\n", ret);
388 if (@available(macOS 10.11, iOS 8.0, *)) {
389 return do_config_output(link);
396#define FLAGS AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_FILTERING_PARAM
397#define CONST(name, help, val, unit) { name, help, 0, AV_OPT_TYPE_CONST, {.i64=val}, INT_MIN, INT_MAX, FLAGS, unit }
399static const AVOption yadif_videotoolbox_options[] = {
400 #define OFFSET(x) offsetof(YADIFContext, x)
422static const AVFilterPad yadif_videotoolbox_inputs[] = {
431static const AVFilterPad yadif_videotoolbox_outputs[] = {
441 .p.name =
"yadif_videotoolbox",
443 .p.priv_class = &yadif_videotoolbox_class,
446 .init = yadif_videotoolbox_init,
447 .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)