Welcome to Doom9's Forum, THE in-place to be for everyone interested in DVD conversion.

Before you start posting please read the forum rules. By posting to this forum you agree to abide by the rules.

 

Go Back   Doom9's Forum > Capturing and Editing Video > Avisynth Development

 
 
Thread Tools Search this Thread Display Modes
Prev Previous Post   Next Post Next
Old 25th January 2023, 22:45   #1  |  Link
Ceppo
Registered User
 
Join Date: Feb 2016
Location: Nonsense land
Posts: 331
HBD/OPTIMIZATION Request :)

I did this simple sharpening filter who does a 3x3 approximated gaussian blur and adds back the difference, reducing it by heuristic means to not get halo.

Now my request is: can someone HBD this simple plugin and give me some tips on how to make it faster?

Code:
#pragma once
#include <cmath> 
#include <windows.h>
#include <avisynth.h>
using namespace std;

struct CSharpenFilter 
{
    PVideoFrame dst;
    PVideoFrame src;
    int height;
    int row_size;
    int src_pitch; 
    int dst_pitch;
    unsigned char* dstp;
    const unsigned char* srcc;
    const unsigned char* srcp;
    const unsigned char* srcn;

    void GetFrame(PClip child, int n, VideoInfo vi, IScriptEnvironment* env)
    {
        src = child->GetFrame(n,env);
        dst = env->NewVideoFrame(vi);
    }
    void GetPlaneY()
    {
        dstp = dst->GetWritePtr(PLANAR_Y);
        dst_pitch = src->GetPitch(PLANAR_Y);

        srcc = src->GetReadPtr(PLANAR_Y);
        srcp = src->GetReadPtr(PLANAR_Y);
        srcn = src->GetReadPtr(PLANAR_Y);
        src_pitch = src->GetPitch(PLANAR_Y);
        height = src->GetHeight(PLANAR_Y);
        row_size = src->GetRowSize(PLANAR_Y);
    }
    void GetPlaneU()
    {
        dstp = dst->GetWritePtr(PLANAR_U);
        dst_pitch = src->GetPitch(PLANAR_U);

        srcc = src->GetReadPtr(PLANAR_U);
        srcp = src->GetReadPtr(PLANAR_U);
        srcn = src->GetReadPtr(PLANAR_U);
        src_pitch = src->GetPitch(PLANAR_U);
        height = src->GetHeight(PLANAR_U);
        row_size = src->GetRowSize(PLANAR_U);
    }
    void GetPlaneV()
    {
        dstp = dst->GetWritePtr(PLANAR_V);
        dst_pitch = src->GetPitch(PLANAR_V);

        srcc = src->GetReadPtr(PLANAR_V);
        srcp = src->GetReadPtr(PLANAR_V);
        srcn = src->GetReadPtr(PLANAR_V);
        src_pitch = src->GetPitch(PLANAR_V);
        height = src->GetHeight(PLANAR_V);
        row_size = src->GetRowSize(PLANAR_V);
    }
    void CopyPlane()
    {
        int x, y;

        for (y = 0; y < height; y++)
        {
            for (x = 0; x < row_size; x++)
            {
                dstp[x] = srcc[x];
            }
            dstp += dst_pitch;
            srcc += src_pitch;
        }
    }
    //CORE FILTER SUPPORT FUNCTIONS
    int AddDiff(int x, int y, int nt, int mode)
    {
        int i, j, k;

        //GETS DIFF, ABS DIFF, SIGN DIFF;
        i = x - y;
        j = abs(i);
        k = (i > 0) - (i < 0);

        //SET TO 0 LOW FREQUENCY;
        i = j < nt ? 0 : i;
        j = j < nt ? 0 : j;

        //REDUCE DIFFERENCE;
        i = mode > 0 ? (int)sqrt(j) : i;
        i = mode > 1 ? (int)atan(j) * i : i;

        //ADD DIFFERENCE
        i = i * k;
        i = min(255, x + i);
        i = max(  0,     i);

        return i;
    }
    void CoreFilter(int nt, int mode)
    {
        int x, y, i, j, k;
        
        //START PITCH;
        srcp -= src_pitch;
        srcn += src_pitch;

        //FILTER FIRST ROW;
        for (x = 0; x < row_size; x++)
        {
            j = max(0, x - 1);
            k = min(row_size - 1, x + 1);

            i  = srcc[j]     + srcc[x] * 2 + srcc[k];
            i += srcc[j] * 2 + srcc[x] * 4 + srcc[k] * 2;
            i += srcn[j]     + srcn[x] * 2 + srcn[k];
            i  = (int)(i / 16.0f + 0.5f);
            dstp[x] = AddDiff(srcc[x], i, nt, mode);
        }
        dstp += dst_pitch;
        srcp += src_pitch;
        srcc += src_pitch;
        srcn += src_pitch;

        //FILTER MAIN ROWS;
        for (y = 1; y < height - 1; y++)
        {
            for (x = 0; x < row_size; x++)
            {
                j = max(0, x - 1);
                k = min(row_size - 1, x + 1);

                i  = srcp[j]     + srcp[x] * 2 + srcp[k];
                i += srcc[j] * 2 + srcc[x] * 4 + srcc[k] * 2;
                i += srcn[j]     + srcn[x] * 2 + srcn[k];
                i = (int)(i / 16.0f + 0.5f);
                dstp[x] = AddDiff(srcc[x], i, nt, mode);
            }
            dstp += dst_pitch;
            srcp += src_pitch;
            srcc += src_pitch;
            srcn += src_pitch;
        }

        //FILTER LAST ROW;
        for (x = 0; x < row_size; x++)
        {
            j = max(0, x - 1);
            k = min(row_size - 1, x + 1);

            i  = srcp[j]     + srcp[x] * 2 + srcp[k];
            i += srcc[j] * 2 + srcc[x] * 4 + srcc[k] * 2;
            i += srcc[j]     + srcc[x] * 2 + srcc[k];
            i = (int)(i / 16.0f + 0.5f);
            dstp[x] = AddDiff(srcc[x], i, nt, mode);
        }
    }
};

class CSharpen : public GenericVideoFilter
{
    int nt, mode;
    bool Y, U, V;
public:
    CSharpen(PClip _child, int _nt, int _mode, bool _Y, bool _U, bool _V, IScriptEnvironment* env) : GenericVideoFilter(_child), nt(_nt), mode(_mode), Y(_Y), U(_U), V(_V)
    {
        if (!vi.IsYUV())
        {
            env->ThrowError("CSharpen: supported colorspaces are Y8, YV12, YV16, YV24!");
        }
        else if (nt < 0 || nt > 255)
        {
            env->ThrowError("CSharpen: nt avaible range is [0, 255]!");
        }
        else if (mode < 0 || mode > 2)
        {
            env->ThrowError("CSharpen: mode avaible mode values are 0, 1, 2!");
        }
    }
    PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env) 
    {

        CSharpenFilter Frame;
        Frame.GetFrame(child, n, vi, env);

        if (Y) Frame.GetPlaneY();
        if (Y) Frame.CoreFilter(nt, mode);

        if (!vi.IsY8())
        {
            Frame.GetPlaneU();
            U ? Frame.CoreFilter(nt, mode) : Frame.CopyPlane();
            Frame.GetPlaneV();
            V ? Frame.CoreFilter(nt, mode) : Frame.CopyPlane();
        }

        return Frame.dst;
    }
};

const AVS_Linkage* AVS_linkage = 0;

AVSValue __cdecl Create_CSharpen(AVSValue args, void* user_data, IScriptEnvironment* env) 
{
    return new CSharpen(args[0].AsClip(),args[1].AsInt(3),args[2].AsInt(2),args[3].AsBool(true),args[4].AsBool(false),args[5].AsBool(false),env);
}

extern "C" __declspec(dllexport) const char* __stdcall AvisynthPluginInit3(IScriptEnvironment * env, const AVS_Linkage* const vectors)
{
    AVS_linkage = vectors;
    env->AddFunction("CSharpen", "c[nt]i[mode]i[Y]b[U]b[V]b", Create_CSharpen, 0);
    return "CSharpen";
}
__________________
CQTGMC/CTools
I come from nonsense land. I usually post under the effect of alchool and I don't think before writing, so don't get it personal, I didn't mean to.
Ceppo is offline   Reply With Quote
 

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +1. The time now is 16:07.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2023, vBulletin Solutions Inc.