Filter SDK/CMerge
From Avisynth wiki
(Difference between revisions)
Line 115: | Line 115: | ||
avs_release_clip(new_clip); | avs_release_clip(new_clip); | ||
return v; | return v; | ||
− | } | + | } |
− | + | ||
− | + | ||
const char* AVSC_CC avisynth_c_plugin_init(AVS_ScriptEnvironment* env) | const char* AVSC_CC avisynth_c_plugin_init(AVS_ScriptEnvironment* env) | ||
{ | { |
Revision as of 00:02, 29 December 2016
#include "avisynth_c.h" #include <stdlib.h> // free, malloc typedef struct Merge { AVS_Clip* clip2; double weight; } Merge; AVS_VideoFrame* AVSC_CC Merge_get_frame(AVS_FilterInfo* fi, int n) { Merge* params = (Merge*) fi->user_data; AVS_VideoFrame* src = avs_get_frame(fi->child, n); const BYTE* srcp = avs_get_read_ptr(src); int src_pitch = avs_get_pitch(src); AVS_VideoFrame* src2 = avs_get_frame(params->clip2, n); const BYTE* srcp2 = avs_get_read_ptr(src2); int src2_pitch = avs_get_pitch(src2); AVS_VideoFrame* dst = avs_new_video_frame(fi->env, &fi->vi); BYTE* dstp = avs_get_write_ptr(dst); int dst_pitch = avs_get_pitch(dst); int dst_rowsize = avs_get_row_size(dst); // in bytes! int dst_height = avs_get_height(dst); int x, y, ch_tot; double w; if (avs_is_rgb32(&fi->vi)) ch_tot = 4; else // rgb24 ch_tot = 3; w = params->weight; for (y=0; y<dst_height; ++y) { for (x=0; x<dst_rowsize; x+=ch_tot) { dstp[x] = (int)((1-w)*srcp[x] + w*srcp2[x]+0.5); // B dstp[x+1] = (int)((1-w)*srcp[x+1] + w*srcp2[x+1]+0.5); // G dstp[x+2] = (int)((1-w)*srcp[x+2] + w*srcp2[x+2]+0.5); // R } srcp += src_pitch; srcp2 += src2_pitch; dstp += dst_pitch; } avs_release_frame(src); avs_release_frame(src2); return dst; } void AVSC_CC free_Merge(AVS_FilterInfo* fi) { Merge* params = (Merge*) fi->user_data; avs_release_clip(params->clip2); free(params); } AVS_Value AVSC_CC create_Merge(AVS_ScriptEnvironment* env, AVS_Value args, void* user_data) { AVS_Value v; AVS_Value tmp; AVS_FilterInfo* fi; const AVS_VideoInfo* vi2; AVS_Clip* new_clip = avs_new_c_filter(env, &fi, avs_array_elt(args, 0), 1); Merge *params = (Merge*)malloc(sizeof(Merge)); if (!params) return avs_void; if (!avs_is_rgb(&fi->vi)) { return avs_new_value_error("Input video must be in RGB format!"); } tmp = avs_array_elt(args, 1); if (avs_defined(tmp)) { params->clip2 = avs_take_clip(tmp, env); vi2 = avs_get_video_info(params->clip2); if (!avs_has_video(vi2)) { return avs_new_value_error("Second clip must be a video clip!"); } else if (!avs_is_color_space(vi2, fi->vi.pixel_type)) { return avs_new_value_error("Second video must have the same pixel-type as the first clip!"); } else if (vi2->width != fi->vi.width || vi2->height != fi->vi.height) { return avs_new_value_error("Input and second clip sizes must match!"); } } else { return avs_new_value_error("Second clip is missing!"); } tmp = avs_array_elt(args, 2); if (avs_defined(tmp)) { params->weight = avs_as_float(tmp); if ((params->weight<0.0f) || (params->weight>1.0f)) { return avs_new_value_error("Make sure that '0.0 <= weight <= 1.0'!"); } } else { params->weight = 0.5; // default value } fi->user_data = (void*) params; fi->get_frame = Merge_get_frame; fi->free_filter = free_Merge; v = avs_new_value_clip(new_clip); avs_release_clip(new_clip); return v; } const char* AVSC_CC avisynth_c_plugin_init(AVS_ScriptEnvironment* env) { avs_add_function(env, "Merge", "cc[weight]f", create_Merge, 0); return "Merge sample C plugin"; }