#ifndef VIDEOINFOADAPTER_H
#define VIDEOINFOADAPTER_H
struct VideoInfoAdapter {
private:
const VSVideoInfo *vsvi = nullptr;
const VSAudioInfo *vsai = nullptr;
const avs::VideoInfo *avsvi = nullptr;
public:
VSVideoFormat vf = {};
int num_frames;
uint32_t fps_numerator;
uint32_t fps_denominator;
int width;
int height;
int64_t num_audio_samples;
int alt_output;
Avisynther_ *avssynther = nullptr;
VapourSynther_ *vssynther = nullptr;
VideoInfoAdapter(const VSVideoInfo *vi, const VSAudioInfo *ai, VapourSynther_ *vssynther, int alt_output) : vsvi(vi), vsai(ai), alt_output(alt_output), vssynther(vssynther) {
num_frames = vi ? vi->numFrames : 0;
fps_numerator = static_cast<uint32_t>(vi ? vi->fpsNum : 0);
fps_denominator = static_cast<uint32_t>(vi ? vi->fpsDen : 0);
width = vi->width;
height = vi->height;
num_audio_samples = ai ? ai->numSamples : 0;
vf = vi->format;
};
VideoInfoAdapter(const avs::VideoInfo *vi, Avisynther_ *avssynther, int alt_output) : avsvi(vi), alt_output(alt_output), avssynther(avssynther) {
num_frames = vi->num_frames;
fps_numerator = vi->fps_numerator;
fps_denominator = vi->fps_denominator;
width = vi->width;
height = vi->height;
num_audio_samples = vi->num_audio_samples;
if (vi->IsPlanar()) {
bool hasSubSampling = vi->IsYUV();
vf.colorFamily = vi->IsYUV() ? cfYUV : (vi->IsRGB() ? cfRGB : (vi->IsY() ? cfGray : cfUndefined));
if (vf.colorFamily != cfUndefined) {
vf.sampleType = vi->BitsPerComponent() == 32 ? stFloat : stInteger;
vf.bitsPerSample = vi->BitsPerComponent();
if (vf.bitsPerSample <= 8)
vf.bytesPerSample = 1;
else if (vf.bitsPerSample <= 16)
vf.bytesPerSample = 2;
else
vf.bytesPerSample = 4;
vf.subSamplingW = hasSubSampling ? vi->GetPlaneWidthSubsampling(avs::PLANAR_U) : 0;
vf.subSamplingH = hasSubSampling ? vi->GetPlaneHeightSubsampling(avs::PLANAR_U) : 0;
vf.numPlanes = (vi->IsYUV() || vi->IsRGB()) ? 3 : 1;
}
} else if (vi->IsRGB24()) {
vf.colorFamily = static_cast<VSColorFamily>(-static_cast<int>(cfRGB));
vf.bitsPerSample = 24;
vf.bytesPerSample = 3;
vf.numPlanes = 1;
} else if (vi->IsRGB32()) {
vf.colorFamily = static_cast<VSColorFamily>(-static_cast<int>(cfRGB));
vf.bitsPerSample = 32;
vf.bytesPerSample = 4;
vf.numPlanes = 1;
} else if (vi->IsYUY2()) {
vf.colorFamily = static_cast<VSColorFamily>(-static_cast<int>(cfYUV));
vf.bitsPerSample = 16;
vf.bytesPerSample = 2;
vf.subSamplingW = 1;
vf.numPlanes = 1;
}
};
bool HasAudio() const {
return vsai || (avsvi && avsvi->HasAudio());
}
bool HasVideo() const {
return vsvi || (avsvi && avsvi->HasVideo());
}
int AudioChannels() const {
if (vsai) {
return vsai->format.numChannels;
} else {
return (avsvi && avsvi->AudioChannels() <= 8) ? avsvi->AudioChannels() : 0;
}
}
uint64_t ChannelLayout() const {
if (vsai) {
return vsai->format.channelLayout;
} else {
if (avsvi && avsvi->AudioChannels() <= 8) {
const uint64_t guessedLayout[9] = { 0x0000, 0x0004, 0x0003, 0x0007, 0x0033, 0x0037, 0x003F, 0x013F, 0x063F };
return guessedLayout[avsvi->AudioChannels()];
}
return 0;
}
}
int SamplesPerSecond() const {
if (vsai)
return vsai->sampleRate;
else
return avsvi ? avsvi->SamplesPerSecond() : 0;
}
int BytesPerChannelSample() const {
if (vsai)
return vsai->format.bytesPerSample;
else
return avsvi ? avsvi->BytesPerChannelSample() : 0;
}
int64_t AudioSamplesFromFrames(int frames) const {
if (vsvi && vsai && vsvi->fpsNum > 0)
return static_cast<int64_t>(frames) * vsai->sampleRate * vsvi->fpsDen / vsvi->fpsNum;
else if (avsvi)
return avsvi->AudioSamplesFromFrames(frames);
else
return 0;
}
int FramesFromAudioSamples(int64_t samples) const {
if (vsvi && vsai && vsvi->fpsDen > 0)
return static_cast<int>((samples * vsvi->fpsNum) / (static_cast<int64_t>(fps_denominator) * vsai->sampleRate));
else if (avsvi)
return avsvi->FramesFromAudioSamples(samples);
else
return 0;
}
int BytesPerAudioSample() const {
if (vsai)
return vsai->format.bytesPerSample * vsai->format.numChannels;
else
return avsvi ? avsvi->BytesPerAudioSample() : 0;
}
int BitsPerChannelSample() const {
if (vsai)
return vsai->format.bitsPerSample;
else
return avsvi ? (avsvi->BytesPerChannelSample() * 8) : 0;
}
int BMPSize() const {
return vsvi ? vssynther->BMPSize() : avssynther->BMPSize();
}
int BitsPerPixel() const {
return vsvi ? vssynther->BitsPerPixel() : avssynther->BitsPerPixel();
}
bool AudioIsFloat() const {
if (avsvi && avsvi->sample_type == avs::SAMPLE_FLOAT)
return true;
if (vsai && vsai->format.sampleType == stFloat)
return true;
return false;
}
};
#endif