ok, thanks for looking at it
Code:
// HistByLine plugin
//
// Written by jmac698
// Copyleft 8-14-2014
//
// You may use this plugin however you wish,
// and distribute it under the terms of the GNU GPL.
//
// HISTORY:
// - Alpha 0.3: mode 0 is implemented and works, returns YV12 output only
// - tested with inputs of YV12, YUY2, Y8
//
// Plugin parameters:
// ------------------
// HistByLine(clip, int mode)
//
// clip clip: input clip, can be YUY2, YV12 or Y8
// int mode (default: 0):
// 0 - if count>0 then luma=255
// 1 - scaled count with 255=1.0
// 2 - lsb of count
// 3 - msb of count
//
// output: RGB32 color image
//
// Based on DemosaicCPP by StainlessS
#include <Windows.h>
#include <stdlib.h>
#include <string.h>
#include "Avisynth.h"
// class HistByLineCPP
class HistByLineCPP : public GenericVideoFilter {
private:
// ---------- avisynth.h interface extension - begin ----------
// The following is missing from avisynth.h version 3 and is needed by this v2.5 plugin.
//
// From Avisynth.h Version 5
// CS_Shift_Sample_Bits = 16,
// CS_Sample_Bits_Mask = 7 << CS_Shift_Sample_Bits,
// CS_Sample_Bits_8 = 0 << CS_Shift_Sample_Bits,
//
// Planar match mask 1111.0000.0000.0111.0000.0111.0000.0111 // 0xF0070707
// Planar signature 10xx.0000.0000.00xx.0000.00xx.00xx.00xx // 0xCFFCFCCC, 0x80000000
// Planar filter mask 1111.1111.1111.1111.1111.1111.1100.1111 // 0xFFFFFFCF
//
enum {
V25_CS_Shift_Sample_Bits = 16,
V25_CS_Sample_Bits_Mask = (7 << V25_CS_Shift_Sample_Bits),
V25_CS_Sample_Bits_8 = (0 << V25_CS_Shift_Sample_Bits),
V25_CS_PLANAR_MASK = 0xF0070707,
V25_CS_PLANAR_FILTER = 0xFFFFFFCF,
V25_CS_Y = VideoInfo::CS_PLANAR | VideoInfo::CS_INTERLEAVED | VideoInfo::CS_YUV,
V25_CS_Y8 = V25_CS_Y | V25_CS_Sample_Bits_8
};
bool V25_IsY8(VideoInfo&vix) const { return (vix.pixel_type & V25_CS_PLANAR_MASK) == (V25_CS_Y8 & V25_CS_PLANAR_FILTER);}
// ---------- avisynth_c interface extension - end ----------
const int mode;
VideoInfo src_vi;
public:
HistByLineCPP(PClip _child,int _mode,IScriptEnvironment* env); // Constructor
~HistByLineCPP(); // Destructor
PVideoFrame __stdcall GetFrame(int n, IScriptEnvironment* env); // GetFrame
};
// This is the constructor.
HistByLineCPP::HistByLineCPP(PClip _child,int _mode,IScriptEnvironment* env) :
GenericVideoFilter(_child),mode(_mode) {
if(!vi.IsYV12() && !vi.IsYUY2() && !V25_IsY8(vi)) // Synthesized for Y8
env->ThrowError("Input video format can be: YUY2, YV12, Y8");
src_vi = vi; // remember original source vi.
// we copied the clip type of the source, now we make some modifications
// Set up VideoInfo to return new colorspace YV12
vi.pixel_type = VideoInfo::CS_YV12; // RGB would be CS_BGR32
vi.width = 256; // only need width of 256 to hold histogram samples
}
// This is the destructor definition. This is called when the filter is destroyed.
HistByLineCPP::~HistByLineCPP()
{} // Empty Destructor
// GetFrame() Called by Avisynth to get frame n
PVideoFrame __stdcall HistByLineCPP::GetFrame(int n, IScriptEnvironment* env) {
// destination
PVideoFrame dest_frame;
BYTE* dest_data;
unsigned int dest_pitch;
unsigned int dest_height;
unsigned int dest_row_size;
unsigned int dest_uv_pitch; // for planar (yv12)
unsigned int dest_uv_height;
BYTE* dest_data_u;
BYTE* dest_data_v;
unsigned int dest_uv_row_size;
dest_frame = env->NewVideoFrame(vi);
dest_data = dest_frame->GetWritePtr(PLANAR_Y);
dest_pitch = dest_frame->GetPitch(PLANAR_Y);
dest_height = dest_frame->GetHeight(PLANAR_Y);
dest_row_size = dest_frame->GetRowSize(PLANAR_Y);
dest_uv_pitch = dest_frame->GetPitch(PLANAR_U);
dest_uv_height = dest_frame->GetHeight(PLANAR_U);
dest_data_u = dest_frame->GetWritePtr(PLANAR_U);
dest_data_v = dest_frame->GetWritePtr(PLANAR_V);
dest_uv_row_size = dest_frame->GetRowSize(PLANAR_U);
// source
PVideoFrame src_frame;
CONST BYTE* src_data;
unsigned int src_pitch;
unsigned int src_row_size; // in bytes!
unsigned int src_height;
unsigned int src_inc; // next pixel in row
src_frame = child->GetFrame(n, env);
if(src_vi.IsYV12()) {
src_data = src_frame->GetReadPtr(PLANAR_Y);
src_pitch = src_frame->GetPitch(PLANAR_Y);
src_row_size= src_frame->GetRowSize(PLANAR_Y); // in bytes!
src_height = src_frame->GetHeight(PLANAR_Y);
src_inc = 1;
} else if(src_vi.IsYUY2()) {
src_data = src_frame->GetReadPtr();
src_pitch = src_frame->GetPitch();
src_row_size= src_frame->GetRowSize(); // in bytes!
src_height = src_frame->GetHeight();
src_inc = 2;
} else if(V25_IsY8(src_vi)) {
src_data = src_frame->GetReadPtr();
src_pitch = src_frame->GetPitch();
src_row_size= src_frame->GetRowSize(); // in bytes!
src_height = src_frame->GetHeight();
src_inc = 1;
} else { // somethings very wrong
return dest_frame; // dest_frame is junk ???
}
unsigned int x, y;
// RGB is upside down
// dest_data += (dest_height - 1) * dest_pitch; // only needed if returning RGB
// make dest_frame luma 0
for (y = 0; y < dest_height; ++y) {
for (x = 0; x < dest_row_size; ++x) {
dest_data[x] = 0; // initialize luma of dest frame to 0
}
dest_data += dest_pitch;
}
// make dest_frame grey (for planar formats)
for (y = 0; y < dest_uv_height; ++y) {
for (x = 0; x < dest_uv_row_size; ++x) {
dest_data_u[x] = 128;
dest_data_v[x] = 128;
}
dest_data_u += dest_uv_pitch;
dest_data_v += dest_uv_pitch;
}
dest_data = dest_frame->GetWritePtr(PLANAR_Y); // reset dest_data
for (y = 0; y < src_height; ++y) {
for (x = 0; x < src_row_size; x += src_inc) {
// int mode (default: 0):
// 0 - if count>0 then luma=255
// 1 - scaled count with 255=1.0
// 2 - lsb of count
// 3 - msb of count
if (mode == 0) {
dest_data[src_data[x]] = 255; //assumes dest_data was initialized with 0's
}
}
src_data += src_pitch;
// dest_data -= dest_pitch; // decrement in the case of RGB
dest_data += dest_pitch;
}
return dest_frame;
}
AVSValue __cdecl Create_HistByLineCPP(AVSValue args, void* user_data, IScriptEnvironment* env) {
return new HistByLineCPP( // Arguments to the Filter class Constructor of HistByLineCPP class.
args[0].AsClip(), // Clip
args[1].AsInt(0), // mode
env
);
}
extern "C" __declspec(dllexport) const char* __stdcall AvisynthPluginInit2(IScriptEnvironment* env) {
env->AddFunction(
"HistByLineCPP", // The name of the filter in Avisynth.
"c[mode]i",
Create_HistByLineCPP, // The function Avisynth will call to create an instance of the filter.
0
);
// Arguments is a string that defines the types and optional names of the arguments for you filter.
// c - Video Clip
// i - Integer number
// f - Float number
// s - String
// b - boolean
// . - Any type (dot)
// Array Specifiers
// i* - Integer Array, zero or more
// i+ - Integer Array, one or more
// .* - Any type Array, zero or more
// .+ - Any type Array, one or more
// Etc
return "`HistByLineCPP' HistByLineCPP plugin"; // A freeform name of the plugin.
}