Skip to content

Commit

Permalink
Improve frame server class naming
Browse files Browse the repository at this point in the history
  • Loading branch information
CrendKing committed May 4, 2021
1 parent f59af57 commit c2e6085
Show file tree
Hide file tree
Showing 15 changed files with 257 additions and 265 deletions.
16 changes: 8 additions & 8 deletions avisynth_filter/src/format.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ auto Format::LookupMediaSubtype(const CLSID &mediaSubtype) -> const PixelFormat
return nullptr;
}

auto Format::GetVideoFormat(const AM_MEDIA_TYPE &mediaType, const ScriptInstance *scriptInstance) -> VideoFormat {
auto Format::GetVideoFormat(const AM_MEDIA_TYPE &mediaType, const FrameServerBase *scriptInstance) -> VideoFormat {
const VIDEOINFOHEADER *vih = reinterpret_cast<VIDEOINFOHEADER *>(mediaType.pbFormat);
const REFERENCE_TIME frameDuration = vih->AvgTimePerFrame > 0 ? vih->AvgTimePerFrame : DEFAULT_AVG_TIME_PER_FRAME;

Expand Down Expand Up @@ -122,7 +122,7 @@ auto Format::WriteSample(const VideoFormat &videoFormat, PVideoFrame srcFrame, B
}

auto Format::CreateFrame(const VideoFormat &videoFormat, const BYTE *srcBuffer) -> PVideoFrame {
PVideoFrame frame = MainScriptInstance::GetInstance().GetEnv()->NewVideoFrame(videoFormat.videoInfo, static_cast<int>(_vectorSize));
PVideoFrame frame = MainFrameServer::GetInstance().GetEnv()->NewVideoFrame(videoFormat.videoInfo, static_cast<int>(_vectorSize));

const std::array dstSlices = { frame->GetWritePtr(), frame->GetWritePtr(PLANAR_U), frame->GetWritePtr(PLANAR_V) };
const std::array dstStrides = { frame->GetPitch(), frame->GetPitch(PLANAR_U), frame->GetPitch(PLANAR_V) };
Expand All @@ -147,7 +147,7 @@ auto Format::CopyFromInput(const VideoFormat &videoFormat, const BYTE *srcBuffer
srcMainPlaneStride = -srcMainPlaneStride;
}

MainScriptInstance::GetInstance().GetEnv()->BitBlt(dstSlices[0], dstStrides[0], srcMainPlane, srcMainPlaneStride, rowSize, height);
MainFrameServer::GetInstance().GetEnv()->BitBlt(dstSlices[0], dstStrides[0], srcMainPlane, srcMainPlaneStride, rowSize, height);

if (videoFormat.pixelFormat->fsFormatId & VideoInfo::CS_INTERLEAVED) {
return;
Expand Down Expand Up @@ -195,8 +195,8 @@ auto Format::CopyFromInput(const VideoFormat &videoFormat, const BYTE *srcBuffer
srcV = srcUVPlane2;
}

MainScriptInstance::GetInstance().GetEnv()->BitBlt(dstSlices[1], dstStrides[1], srcU, srcUVStride, srcUVRowSize, srcUVHeight);
MainScriptInstance::GetInstance().GetEnv()->BitBlt(dstSlices[2], dstStrides[2], srcV, srcUVStride, srcUVRowSize, srcUVHeight);
MainFrameServer::GetInstance().GetEnv()->BitBlt(dstSlices[1], dstStrides[1], srcU, srcUVStride, srcUVRowSize, srcUVHeight);
MainFrameServer::GetInstance().GetEnv()->BitBlt(dstSlices[2], dstStrides[2], srcV, srcUVStride, srcUVRowSize, srcUVHeight);
}
}

Expand All @@ -213,7 +213,7 @@ auto Format::CopyToOutput(const VideoFormat &videoFormat, const std::array<const
dstMainPlaneStride = -dstMainPlaneStride;
}

MainScriptInstance::GetInstance().GetEnv()->BitBlt(dstMainPlane, dstMainPlaneStride, srcSlices[0], srcStrides[0], rowSize, height);
MainFrameServer::GetInstance().GetEnv()->BitBlt(dstMainPlane, dstMainPlaneStride, srcSlices[0], srcStrides[0], rowSize, height);

if (videoFormat.pixelFormat->fsFormatId & VideoInfo::CS_INTERLEAVED) {
return;
Expand Down Expand Up @@ -255,8 +255,8 @@ auto Format::CopyToOutput(const VideoFormat &videoFormat, const std::array<const
dstV = dstUVPlane2;
}

MainScriptInstance::GetInstance().GetEnv()->BitBlt(dstU, dstUVStride, srcSlices[1], srcStrides[1], dstUVRowSize, dstUVHeight);
MainScriptInstance::GetInstance().GetEnv()->BitBlt(dstV, dstUVStride, srcSlices[2], srcStrides[2], dstUVRowSize, dstUVHeight);
MainFrameServer::GetInstance().GetEnv()->BitBlt(dstU, dstUVStride, srcSlices[1], srcStrides[1], dstUVRowSize, dstUVHeight);
MainFrameServer::GetInstance().GetEnv()->BitBlt(dstV, dstUVStride, srcSlices[2], srcStrides[2], dstUVRowSize, dstUVHeight);
}
}

Expand Down
16 changes: 8 additions & 8 deletions avisynth_filter/src/frame_handler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ auto FrameHandler::AddInputSample(IMediaSample *inputSample) -> HRESULT {
REFERENCE_TIME inputSampleStopTime = 0;
if (inputSample->GetTime(&inputSampleStartTime, &inputSampleStopTime) == VFW_E_SAMPLE_TIME_NOT_SET) {
// for samples without start time, always treat as fixed frame rate
inputSampleStartTime = _nextSourceFrameNb * MainScriptInstance::GetInstance().GetSourceAvgFrameDuration();
inputSampleStartTime = _nextSourceFrameNb * MainFrameServer::GetInstance().GetSourceAvgFrameDuration();
}

{
Expand Down Expand Up @@ -130,7 +130,7 @@ auto FrameHandler::GetSourceFrame(int frameNb) -> PVideoFrame {
Environment::GetInstance().Log(L"Bad frame %6i", frameNb);
}

return MainScriptInstance::GetInstance().GetSourceDrainFrame();
return MainFrameServer::GetInstance().GetSourceDrainFrame();
}

return iter->second.frame;
Expand Down Expand Up @@ -193,7 +193,7 @@ auto FrameHandler::Stop() -> void {
*
* If no stop here, since AddInputSample() no longer adds frame, existing GetSourceFrame() calls will stuck forever.
*/
MainScriptInstance::GetInstance().StopScript();
MainFrameServer::GetInstance().StopScript();
});

if (_workerThread.joinable()) {
Expand Down Expand Up @@ -255,7 +255,7 @@ auto FrameHandler::PrepareOutputSample(ATL::CComPtr<IMediaSample> &sample, REFER

if (pmtOut != nullptr && pmtOut->pbFormat != nullptr) {
_filter.m_pOutput->SetMediaType(static_cast<CMediaType *>(pmtOut));
_filter._outputVideoFormat = Format::GetVideoFormat(*pmtOut, &MainScriptInstance::GetInstance());
_filter._outputVideoFormat = Format::GetVideoFormat(*pmtOut, &MainFrameServer::GetInstance());
sample->SetMediaType(&_filter.m_pOutput->CurrentMediaType());

Environment::GetInstance().Log(L"New output format: name %s, width %5li, height %5li",
Expand All @@ -277,7 +277,7 @@ auto FrameHandler::PrepareOutputSample(ATL::CComPtr<IMediaSample> &sample, REFER
} else {
try {
// some AviSynth internal filter (e.g. Subtitle) can't tolerate multi-thread access
const PVideoFrame scriptFrame = MainScriptInstance::GetInstance().GetFrame(_nextOutputFrameNb);
const PVideoFrame scriptFrame = MainFrameServer::GetInstance().GetFrame(_nextOutputFrameNb);
Format::WriteSample(_filter._outputVideoFormat, scriptFrame, outputBuffer);
} catch (AvisynthError) {
return false;
Expand Down Expand Up @@ -341,8 +341,8 @@ auto FrameHandler::WorkerProc() -> void {
++processSourceFrameIters[i];

outputFrameDurations[i - 1] = llMulDiv(processSourceFrameIters[i]->second.startTime - processSourceFrameIters[i - 1]->second.startTime,
MainScriptInstance::GetInstance().GetScriptAvgFrameDuration(),
MainScriptInstance::GetInstance().GetSourceAvgFrameDuration(),
MainFrameServer::GetInstance().GetScriptAvgFrameDuration(),
MainFrameServer::GetInstance().GetSourceAvgFrameDuration(),
0);
}
}
Expand Down Expand Up @@ -418,7 +418,7 @@ auto FrameHandler::ChangeOutputFormat() -> bool {

BeginFlush();
EndFlush([this]() -> void {
MainScriptInstance::GetInstance().ReloadScript(_filter.m_pInput->CurrentMediaType(), true);
MainFrameServer::GetInstance().ReloadScript(_filter.m_pInput->CurrentMediaType(), true);
});

_filter._changeOutputMediaType = false;
Expand Down
133 changes: 64 additions & 69 deletions avisynth_filter/src/frameserver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "frameserver.h"
#include "api.h"
#include "constants.h"
#include "source_clip.h"


const AVS_Linkage *AVS_linkage = nullptr;
Expand All @@ -19,28 +20,72 @@ auto __cdecl Create_AvsFilterDisconnect(AVSValue args, void *user_data, IScriptE
return AVSValue();
}

ScriptInstance::ScriptInstance()
: _env(FrameServer::GetInstance().CreateEnv()) {
FrameServerCommon::FrameServerCommon() {
Environment::GetInstance().Log(L"FrameServerCommon()");

IScriptEnvironment *env = CreateEnv();
AVS_linkage = env->GetAVSLinkage();
_versionString = env->Invoke("Eval", AVSValue("VersionString()")).AsString();
Environment::GetInstance().Log(L"AviSynth version: %S", GetVersionString());
env->DeleteScriptEnvironment();

_sourceClip = new SourceClip(_sourceVideoInfo);
}

ScriptInstance::~ScriptInstance() {
FrameServerCommon::~FrameServerCommon() {
Environment::GetInstance().Log(L"~FrameServerCommon()");

_sourceClip = nullptr;
AVS_linkage = nullptr;
}

auto FrameServerCommon::SetScriptPath(const std::filesystem::path &scriptPath) -> void {
_scriptPath = scriptPath;
}

auto FrameServerCommon::LinkFrameHandler(FrameHandler *frameHandler) const -> void {
reinterpret_cast<SourceClip *>(_sourceClip.operator->())->SetFrameHandler(frameHandler);
}

auto FrameServerCommon::CreateEnv() const -> IScriptEnvironment * {
/*
use CreateScriptEnvironment() instead of CreateScriptEnvironment2().
CreateScriptEnvironment() is exported from their .def file, which guarantees a stable exported name.
CreateScriptEnvironment2() was not exported that way, thus has different names between x64 and x86 builds.
We don't use any new feature from IScriptEnvironment2 anyway.
*/
IScriptEnvironment *env = CreateScriptEnvironment(MINIMUM_AVISYNTH_PLUS_INTERFACE_VERSION);
if (env == nullptr) {
const WCHAR *errorMessage = L"CreateScriptEnvironment() returns nullptr";
Environment::GetInstance().Log(errorMessage);
MessageBoxW(nullptr, errorMessage, FILTER_NAME_FULL, MB_ICONERROR);
throw;
}

env->AddFunction("AvsFilterSource", "", Create_AvsFilterSource, _sourceClip);
env->AddFunction("AvsFilterDisconnect", "", Create_AvsFilterDisconnect, nullptr);

return env;
}

FrameServerBase::~FrameServerBase() {
StopScript();
_env->DeleteScriptEnvironment();
}

/**
* Create new script clip with specified media type.
*/
auto ScriptInstance::ReloadScript(const AM_MEDIA_TYPE &mediaType, bool ignoreDisconnect) -> bool {
auto FrameServerBase::ReloadScript(const AM_MEDIA_TYPE &mediaType, bool ignoreDisconnect) -> bool {
StopScript();

FrameServer::GetInstance()._sourceVideoInfo = Format::GetVideoFormat(mediaType, this).videoInfo;
FrameServerCommon::GetInstance()._sourceVideoInfo = Format::GetVideoFormat(mediaType, this).videoInfo;

_errorString.clear();
AVSValue invokeResult;

if (!FrameServer::GetInstance()._scriptPath.empty()) {
const std::string utf8Filename = ConvertWideToUtf8(FrameServer::GetInstance()._scriptPath);
if (!FrameServerCommon::GetInstance()._scriptPath.empty()) {
const std::string utf8Filename = ConvertWideToUtf8(FrameServerCommon::GetInstance()._scriptPath);
const std::array<AVSValue, 2> args = { utf8Filename.c_str(), true };
const std::array<char *const, args.size()> argNames = { nullptr, "utf8" };

Expand All @@ -57,7 +102,7 @@ auto ScriptInstance::ReloadScript(const AM_MEDIA_TYPE &mediaType, bool ignoreDis
return false;
}

invokeResult = FrameServer::GetInstance()._sourceClip;
invokeResult = FrameServerCommon::GetInstance()._sourceClip;
} else if (!invokeResult.IsClip()) {
_errorString = "Error: Script does not return a clip.";
}
Expand All @@ -83,40 +128,40 @@ auto ScriptInstance::ReloadScript(const AM_MEDIA_TYPE &mediaType, bool ignoreDis
return true;
}

auto ScriptInstance::StopScript() -> void {
auto FrameServerBase::StopScript() -> void {
if (_scriptClip != nullptr) {
Environment::GetInstance().Log(L"Release script clip: %p", _scriptClip);
_scriptClip = nullptr;
}
}

MainScriptInstance::~MainScriptInstance() {
MainFrameServer::~MainFrameServer() {
_sourceDrainFrame = nullptr;
}

auto MainScriptInstance::ReloadScript(const AM_MEDIA_TYPE &mediaType, bool ignoreDisconnect) -> bool {
auto MainFrameServer::ReloadScript(const AM_MEDIA_TYPE &mediaType, bool ignoreDisconnect) -> bool {
Environment::GetInstance().Log(L"ReloadScript from main instance");

if (__super::ReloadScript(mediaType, ignoreDisconnect)) {
_sourceDrainFrame = _env->NewVideoFrame(FrameServer::GetInstance()._sourceVideoInfo);
_sourceAvgFrameRate = static_cast<int>(llMulDiv(FrameServer::GetInstance()._sourceVideoInfo.fps_numerator, FRAME_RATE_SCALE_FACTOR, _scriptVideoInfo.fps_denominator, 0));
_sourceAvgFrameDuration = llMulDiv(FrameServer::GetInstance()._sourceVideoInfo.fps_denominator, UNITS, FrameServer::GetInstance()._sourceVideoInfo.fps_numerator, 0);
_sourceDrainFrame = _env->NewVideoFrame(FrameServerCommon::GetInstance()._sourceVideoInfo);
_sourceAvgFrameRate = static_cast<int>(llMulDiv(FrameServerCommon::GetInstance()._sourceVideoInfo.fps_numerator, FRAME_RATE_SCALE_FACTOR, _scriptVideoInfo.fps_denominator, 0));
_sourceAvgFrameDuration = llMulDiv(FrameServerCommon::GetInstance()._sourceVideoInfo.fps_denominator, UNITS, FrameServerCommon::GetInstance()._sourceVideoInfo.fps_numerator, 0);

return true;
}

return false;
}

auto MainScriptInstance::GetFrame(int frameNb) const -> PVideoFrame {
auto MainFrameServer::GetFrame(int frameNb) const -> PVideoFrame {
return _scriptClip->GetFrame(frameNb, _env);
}

auto MainScriptInstance::GetErrorString() const -> std::optional<std::string> {
auto MainFrameServer::GetErrorString() const -> std::optional<std::string> {
return _errorString.empty() ? std::nullopt : std::make_optional(_errorString);
}

auto CheckingScriptInstance::ReloadScript(const AM_MEDIA_TYPE &mediaType, bool ignoreDisconnect) -> bool {
auto AuxFrameServer::ReloadScript(const AM_MEDIA_TYPE &mediaType, bool ignoreDisconnect) -> bool {
Environment::GetInstance().Log(L"ReloadScript from checking instance");

if (__super::ReloadScript(mediaType, ignoreDisconnect)) {
Expand All @@ -125,7 +170,7 @@ auto CheckingScriptInstance::ReloadScript(const AM_MEDIA_TYPE &mediaType, bool i
// AviSynth+ prefetchers are only destroyed when the environment is deleted
// just stopping the script clip is not enough
_env->DeleteScriptEnvironment();
_env = FrameServer::GetInstance().CreateEnv();
_env = FrameServerCommon::GetInstance().CreateEnv();

return true;
}
Expand All @@ -139,7 +184,7 @@ auto CheckingScriptInstance::ReloadScript(const AM_MEDIA_TYPE &mediaType, bool i
* For example, when the original subtype has 8-bit samples and new subtype has 16-bit,
* all "size" and FourCC values will be adjusted.
*/
auto CheckingScriptInstance::GenerateMediaType(const Format::PixelFormat &pixelFormat, const AM_MEDIA_TYPE *templateMediaType) const -> CMediaType {
auto AuxFrameServer::GenerateMediaType(const Format::PixelFormat &pixelFormat, const AM_MEDIA_TYPE *templateMediaType) const -> CMediaType {
FOURCCMap fourCC(&pixelFormat.mediaSubtype);

CMediaType newMediaType(*templateMediaType);
Expand Down Expand Up @@ -185,54 +230,4 @@ auto CheckingScriptInstance::GenerateMediaType(const Format::PixelFormat &pixelF
return newMediaType;
}

FrameServer::FrameServer() {
IScriptEnvironment *env = CreateEnv();
AVS_linkage = env->GetAVSLinkage();
_versionString = env->Invoke("Eval", AVSValue("VersionString()")).AsString();
env->DeleteScriptEnvironment();

Environment::GetInstance().Log(L"FrameServer()");
Environment::GetInstance().Log(L"Filter version: %S", FILTER_VERSION_STRING);
Environment::GetInstance().Log(L"AviSynth version: %S", GetVersionString());

_sourceClip = new SourceClip(_sourceVideoInfo);
}

FrameServer::~FrameServer() {
Environment::GetInstance().Log(L"~FrameServer()");

_sourceClip = nullptr;

AVS_linkage = nullptr;
}

auto FrameServer::SetScriptPath(const std::filesystem::path &scriptPath) -> void {
_scriptPath = scriptPath;
}

auto FrameServer::LinkFrameHandler(FrameHandler *frameHandler) const -> void {
reinterpret_cast<SourceClip *>(_sourceClip.operator->())->SetFrameHandler(frameHandler);
}

auto FrameServer::CreateEnv() const -> IScriptEnvironment * {
/*
use CreateScriptEnvironment() instead of CreateScriptEnvironment2().
CreateScriptEnvironment() is exported from their .def file, which guarantees a stable exported name.
CreateScriptEnvironment2() was not exported that way, thus has different names between x64 and x86 builds.
We don't use any new feature from IScriptEnvironment2 anyway.
*/
IScriptEnvironment *env = CreateScriptEnvironment(MINIMUM_AVISYNTH_PLUS_INTERFACE_VERSION);
if (env == nullptr) {
const WCHAR *errorMessage = L"CreateScriptEnvironment() returns nullptr";
Environment::GetInstance().Log(errorMessage);
MessageBoxW(nullptr, errorMessage, FILTER_NAME_FULL, MB_ICONERROR);
throw;
}

env->AddFunction("AvsFilterSource", "", Create_AvsFilterSource, _sourceClip);
env->AddFunction("AvsFilterDisconnect", "", Create_AvsFilterDisconnect, nullptr);

return env;
}

}
Loading

0 comments on commit c2e6085

Please sign in to comment.