📄 edit.cpp
字号:
// Avisynth v0.3. Copyright 2000 Ben Rudiak-Gould. For distribution
// conditions, please see http://www.math.berkeley.edu/~benrg/avisynth.html .
#include "avisynth.h"
#include "internal-filters.h"
class ComplementParity : public GenericVideoFilter {
public:
ComplementParity(PVideoFilter _child) : GenericVideoFilter(_child) {}
bool GetParity(int n) { return !child->GetParity(n); }
static PVideoFilter __cdecl Create(const FilterInfo*, const Arg* args, const char*) { return new ComplementParity(args[0].clip); }
};
class AssumeFieldBased : public GenericVideoFilter {
public:
AssumeFieldBased(PVideoFilter _child) : GenericVideoFilter(_child) { vi.field_based = true; }
bool GetParity(int n) { return n&1; }
static PVideoFilter __cdecl Create(const FilterInfo*, const Arg* args, const char*) { return new AssumeFieldBased(args[0].clip); }
};
class AssumeFrameBased : public GenericVideoFilter {
public:
AssumeFrameBased(PVideoFilter _child) : GenericVideoFilter(_child) { vi.field_based = false; }
bool GetParity(int n) { return false; }
static PVideoFilter __cdecl Create(const FilterInfo*, const Arg* args, const char*) { return new AssumeFrameBased(args[0].clip); }
};
class SeparateFields : public GenericVideoFilter {
unsigned char* mybuffer;
int current_frame;
public:
SeparateFields(PVideoFilter _child);
void GetFrame(int n, unsigned char* buf);
void GetVideoInfo(VideoInfo* pvi);
bool GetParity(int n);
~SeparateFields();
static PVideoFilter __cdecl Create(const FilterInfo*, const Arg* args, const char*) {
PVideoFilter clip = args[0].clip;
VideoInfo vi; clip->GetVideoInfo(&vi);
return (vi.field_based) ? clip : new SeparateFields(clip);
}
};
class DoubleWeaveFields : public GenericVideoFilter {
unsigned char* mybuffer;
int current_field;
void CopyField(unsigned char* dst, unsigned char* src, bool parity);
public:
DoubleWeaveFields(PVideoFilter _child);
void GetFrame(int n, unsigned char* buf);
// bool GetParity(int n);
void GetVideoInfo(VideoInfo* pvi);
~DoubleWeaveFields();
};
class DoubleWeaveFrames : public GenericVideoFilter {
unsigned char* frame;
int frame_num;
void CopyAlternateLines(unsigned char* dst, unsigned char* src, bool parity);
public:
DoubleWeaveFrames(PVideoFilter _child);
void GetFrame(int n, unsigned char* buf);
bool GetParity(int n);
void GetVideoInfo(VideoInfo* pvi);
~DoubleWeaveFrames();
};
class Interleave : public VideoFilterWithRefcount {
const int num_children;
const PVideoFilter* child_array;
public:
Interleave(int _num_children, const PVideoFilter* _child_array) : num_children(_num_children), child_array(_child_array) {}
void GetFrame(int n, unsigned char* buf) { child_array[n % num_children]->GetFrame(n / num_children, buf); }
void GetAudio(void* buf, int start, int count) { child_array[0]->GetAudio(buf, start, count); }
void GetVideoInfo(VideoInfo* pvi) {
child_array[0]->GetVideoInfo(pvi);
pvi->fps_numerator *= num_children;
pvi->num_frames = (pvi->num_frames - 1) * num_children + 1;
for (int i=1; i<num_children; ++i) {
VideoInfo vi2;
child_array[i]->GetVideoInfo(&vi2);
if (pvi->width != vi2.width || pvi->height != vi2.height || pvi->pixel_type != vi2.pixel_type)
throw FilterChainError("Interleave: video attributes of all streams must be identical");
pvi->num_frames = max(pvi->num_frames, (vi2.num_frames - 1) * num_children + i + 1);
}
}
bool GetParity(int n) { return child_array[n % num_children]->GetParity(n / num_children); }
~Interleave() { delete[] child_array; }
static PVideoFilter __cdecl Create(const FilterInfo*, const Arg* args, const char* arg_types) {
int num_children = lstrlen(arg_types);
PVideoFilter* child_array = new PVideoFilter[num_children];
for (int i=0; i<num_children; ++i)
child_array[i] = args[i].clip;
return new Interleave(num_children, child_array);
}
};
class SelectEvery : public GenericVideoFilter {
const int every, from;
public:
SelectEvery(int _every, int _from, PVideoFilter _child);
void GetFrame(int n, unsigned char* buf);
void GetVideoInfo(VideoInfo* pvi);
bool GetParity(int n);
static PVideoFilter __cdecl Create(const FilterInfo*, const Arg* args, const char* arg_types) {
int int_args = strchr(arg_types, 'c') - arg_types;
if (int_args <= 2)
return new SelectEvery(args[0].integer, int_args==2 ? args[1].integer : 0, args[int_args].clip);
else {
PVideoFilter* child_array = new PVideoFilter[int_args-1];
for (int i=1; i<int_args; ++i)
child_array[i-1] = new SelectEvery(args[0].integer, args[i].integer, args[int_args].clip);
return new Interleave(int_args-1, child_array);
}
}
static PVideoFilter __cdecl Create_SelectEven(const FilterInfo*, const Arg* args, const char*) { return new SelectEvery(2, 0, args[0].clip); }
static PVideoFilter __cdecl Create_SelectOdd(const FilterInfo*, const Arg* args, const char*) { return new SelectEvery(2, 1, args[0].clip); }
};
class Trim : public GenericVideoFilter {
int firstframe, lastframe;
int audio_offset;
public:
Trim(int _firstframe, int _lastframe, PVideoFilter _child);
void GetVideoInfo(VideoInfo* pvi);
void GetFrame(int n, unsigned char* buf);
void GetAudio(void* buf, int start, int count);
bool GetParity(int n);
static PVideoFilter __cdecl Create(const FilterInfo*, const Arg* args, const char*) {
return new Trim(args[0].integer, args[1].integer, args[2].clip);
}
};
class FreezeFrame : public GenericVideoFilter {
const int first, last, source;
public:
FreezeFrame(int _first, int _last, int _source, PVideoFilter _child);
void GetFrame(int n, unsigned char* buf);
bool GetParity(int n);
static PVideoFilter __cdecl Create(const FilterInfo*, const Arg* args, const char*) {
return new FreezeFrame(args[0].integer, args[1].integer, args[2].integer, args[3].clip);
}
};
class DeleteFrame : public GenericVideoFilter {
const int frame;
public:
DeleteFrame(int _frame, PVideoFilter _child);
void GetVideoInfo(VideoInfo* pvi);
void GetFrame(int n, unsigned char* buf);
bool GetParity(int n);
static PVideoFilter __cdecl Create(const FilterInfo*, const Arg* args, const char*) {
return new DeleteFrame(args[0].integer, args[1].clip);
}
};
class DuplicateFrame : public GenericVideoFilter {
const int frame;
public:
DuplicateFrame(int _frame, PVideoFilter _child);
void GetVideoInfo(VideoInfo* pvi);
void GetFrame(int n, unsigned char* buf);
bool GetParity(int n);
static PVideoFilter __cdecl Create(const FilterInfo*, const Arg* args, const char*) {
return new DuplicateFrame(args[0].integer, args[1].clip);
}
};
class Splice : public VideoFilterWithRefcount {
const PVideoFilter child1, child2;
VideoInfo vi1, vi2;
int audio_switchover_point;
public:
Splice(bool realign_sound, PVideoFilter _child1, PVideoFilter _child2);
void GetFrame(int n, unsigned char* buf);
void GetAudio(void* buf, int start, int count);
void GetVideoInfo(VideoInfo* pvi);
bool GetParity(int n);
static PVideoFilter __cdecl CreateUnaligned(const FilterInfo* self, const Arg* args, const char* arg_types) {
if (arg_types[1])
return new Splice(false, args[0].clip, CreateUnaligned(self, args+1, arg_types+1));
else
return args[0].clip;
}
static PVideoFilter __cdecl CreateAligned(const FilterInfo* self, const Arg* args, const char* arg_types) {
if (arg_types[1])
return new Splice(true, args[0].clip, CreateAligned(self, args+1, arg_types+1));
else
return args[0].clip;
}
};
class Dissolve : public VideoFilterWithRefcount {
const PVideoFilter child1, child2;
VideoInfo vi1, vi2;
const int overlap;
int audio_fade_start, audio_fade_end;
unsigned char* vidbuffer;
unsigned char* audbuffer;
int audbufsize;
void EnsureBuffer(int minsize);
public:
Dissolve(int _overlap, PVideoFilter _child1, PVideoFilter _child2);
void GetFrame(int n, unsigned char* buf);
virtual void GetAudio(void* buf, int start, int count);
void GetVideoInfo(VideoInfo* pvi);
bool GetParity(int n);
static PVideoFilter __cdecl Create(const FilterInfo* self, const Arg* args, const char* arg_types) {
PVideoFilter result = args[1].clip;
for (int i=2; arg_types[i]; ++i)
result = new Dissolve(args[0].integer, result, args[i].clip);
return result;
}
};
class AudioDub : public VideoFilterWithRefcount {
/*const*/ PVideoFilter vchild, achild;
public:
AudioDub(PVideoFilter child1, PVideoFilter child2);
void GetFrame(int n, unsigned char* buf);
void GetAudio(void* buf, int start, int count);
void GetVideoInfo(VideoInfo* pvi);
bool GetParity(int n);
static PVideoFilter __cdecl Create(const FilterInfo* self, const Arg* args, const char*) {
return new AudioDub(args[0].clip, args[1].clip);
}
};
class DelayAudio : public GenericVideoFilter {
const int delay_samples;
public:
DelayAudio(float delay, PVideoFilter _child);
virtual void GetVideoInfo(VideoInfo* pvi);
virtual void GetAudio(void* buf, int start, int count);
static PVideoFilter __cdecl Create(const FilterInfo* self, const Arg* args, const char*) {
return new DelayAudio(args[0].floating_pt, args[1].clip);
}
};
class Reverse : public GenericVideoFilter {
public:
Reverse(PVideoFilter _child);
void GetFrame(int n, unsigned char* buf);
bool GetParity(int n);
void GetAudio(void* buf, int start, int count);
static PVideoFilter __cdecl Create(const FilterInfo* self, const Arg* args, const char*) {
return new Reverse(args[0].clip);
}
};
/********************************************************************
********************************************************************/
SeparateFields::SeparateFields(PVideoFilter _child)
: GenericVideoFilter(_child), mybuffer(0)
{
if (vi.height & 1)
throw FilterChainError("SeparateFields: height must be even");
}
void SeparateFields::GetFrame(int n, unsigned char* buf) {
if (!mybuffer || current_frame != (n>>1)) {
if (!mybuffer)
mybuffer = new unsigned char[vi.ImageSize()];
child->GetFrame(n>>1, mybuffer);
current_frame = n>>1;
}
int line_width = vi.ImageSize() / vi.height;
int start_line = (GetParity(n) ^ vi.IsYUY2());
for (int i = start_line; i < vi.height; i += 2)
memcpy(buf+(i>>1)*line_width, mybuffer+i*line_width, line_width);
}
void SeparateFields::GetVideoInfo(VideoInfo* pvi) {
*pvi = vi;
pvi->height >>= 1;
pvi->fps_numerator *= 2;
pvi->num_frames *= 2;
pvi->field_based = true;
}
bool SeparateFields::GetParity(int n) { return child->GetParity(n>>1) ^ (n&1); }
SeparateFields::~SeparateFields() { if (mybuffer) delete[] mybuffer; }
/********************************************************************
********************************************************************/
void DoubleWeaveFields::CopyField(unsigned char* dst, unsigned char* src, bool parity) {
int row_size = vi.RowSize();
if (parity ^ vi.IsYUY2()) dst += row_size;
int offset = 0;
for (int y = vi.height; y; --y) {
memcpy(dst+offset*2, src+offset, row_size);
offset += row_size;
}
}
DoubleWeaveFields::DoubleWeaveFields(PVideoFilter _child) : GenericVideoFilter(_child), mybuffer(0), current_field(-1) {}
void DoubleWeaveFields::GetFrame(int n, unsigned char* buf) {
if (!mybuffer)
mybuffer = new unsigned char[vi.ImageSize()];
bool parity = child->GetParity(n);
if (current_field != n)
child->GetFrame(n, mybuffer);
CopyField(buf, mybuffer, parity);
child->GetFrame(n+1, mybuffer);
current_field = n+1;
CopyField(buf, mybuffer, !parity);
}
void DoubleWeaveFields::GetVideoInfo(VideoInfo* pvi) {
*pvi = vi;
pvi->height *= 2;
pvi->field_based = false;
}
DoubleWeaveFields::~DoubleWeaveFields() { if (mybuffer) delete[] mybuffer; }
/********************************************************************
********************************************************************/
void DoubleWeaveFrames::CopyAlternateLines(unsigned char* dst, unsigned char* src, bool parity) {
int row_size = vi.RowSize();
int offset = (parity ^ vi.IsYUY2()) * row_size;
for (int y = vi.height>>1; y; --y) {
memcpy(dst+offset, src+offset, row_size);
offset += row_size*2;
}
}
DoubleWeaveFrames::DoubleWeaveFrames(PVideoFilter _child)
: GenericVideoFilter(_child), frame(0) {}
void DoubleWeaveFrames::GetFrame(int n, unsigned char* buf) {
if (frame && (n>>1) == frame_num)
memcpy(buf, frame, vi.ImageSize());
else
child->GetFrame(n>>1, buf);
if (n&1) {
if (!frame || frame_num != ((n+1)>>1)) {
if (!frame)
frame = new unsigned char[vi.ImageSize()];
child->GetFrame(frame_num = (n+1)>>1, frame);
}
CopyAlternateLines(buf, frame, !this->GetParity(n));
}
}
bool DoubleWeaveFrames::GetParity(int n) { return child->GetParity(n>>1) ^ (n&1); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -