void VSVideoSource::InitOutputFormat(int ResizeToWidth, int ResizeToHeight, const char *ResizerName, int ConvertToFormat, const VSAPI *vsapi, VSCore *core) { char ErrorMsg[1024]; FFMS_ErrorInfo E; E.Buffer = ErrorMsg; E.BufferSize = sizeof(ErrorMsg); const FFMS_Frame *F = FFMS_GetFrame(V, 0, &E); if (!F) { std::string buf = "Source: "; buf += E.Buffer; throw std::runtime_error(buf); } std::vector<int> TargetFormats; int npixfmt = GetNumPixFmts(); for (int i = 0; i < npixfmt; i++) if (IsRealNativeEndianPlanar(*av_pix_fmt_desc_get((AVPixelFormat)i))) TargetFormats.push_back(i); TargetFormats.push_back(PIX_FMT_NONE); int TargetPixelFormat = PIX_FMT_NONE; if (ConvertToFormat != pfNone) { TargetPixelFormat = FormatConversionToPixelFormat(ConvertToFormat, OutputAlpha, core, vsapi); if (TargetPixelFormat == PIX_FMT_NONE) throw std::runtime_error(std::string("Source: Invalid output colorspace specified")); TargetFormats.clear(); TargetFormats.push_back(TargetPixelFormat); TargetFormats.push_back(-1); } if (ResizeToWidth <= 0) ResizeToWidth = F->EncodedWidth; if (ResizeToHeight <= 0) ResizeToHeight = F->EncodedHeight; int Resizer = ResizerNameToSWSResizer(ResizerName); if (Resizer == 0) throw std::runtime_error(std::string("Source: Invalid resizer name specified")); if (FFMS_SetOutputFormatV2(V, &TargetFormats[0], ResizeToWidth, ResizeToHeight, Resizer, &E)) throw std::runtime_error(std::string("Source: No suitable output format found")); F = FFMS_GetFrame(V, 0, &E); TargetFormats.clear(); TargetFormats.push_back(F->ConvertedPixelFormat); TargetFormats.push_back(-1); // This trick is required to first get the "best" default format and then set only that format as the output if (FFMS_SetOutputFormatV2(V, TargetFormats.data(), ResizeToWidth, ResizeToHeight, Resizer, &E)) throw std::runtime_error(std::string("Source: No suitable output format found")); F = FFMS_GetFrame(V, 0, &E); // Don't output alpha if the clip doesn't have it if (!HasAlpha(*av_pix_fmt_desc_get((AVPixelFormat)F->ConvertedPixelFormat))) OutputAlpha = false; VI[0].format = FormatConversionToVS(F->ConvertedPixelFormat, core, vsapi); if (!VI[0].format) throw std::runtime_error(std::string("Source: No suitable output format found")); VI[0].width = F->ScaledWidth; VI[0].height = F->ScaledHeight; // fixme? Crop to obey sane even width/height requirements }
void AvisynthVideoSource::InitOutputFormat( int ResizeToWidth, int ResizeToHeight, const char *ResizerName, const char *ConvertToFormatName, IScriptEnvironment *Env) { ErrorInfo E; const FFMS_VideoProperties *VP = FFMS_GetVideoProperties(V); const FFMS_Frame *F = FFMS_GetFrame(V, 0, &E); if (!F) Env->ThrowError("FFVideoSource: %s", E.Buffer); std::vector<int> TargetFormats; if (HighBitDepth) { TargetFormats.push_back(FFMS_GetPixFmt("yuv420p16")); TargetFormats.push_back(FFMS_GetPixFmt("yuva420p16")); TargetFormats.push_back(FFMS_GetPixFmt("yuv422p16")); TargetFormats.push_back(FFMS_GetPixFmt("yuva422p16")); TargetFormats.push_back(FFMS_GetPixFmt("yuv444p16")); TargetFormats.push_back(FFMS_GetPixFmt("yuva444p16")); TargetFormats.push_back(FFMS_GetPixFmt("yuv420p10")); TargetFormats.push_back(FFMS_GetPixFmt("yuva420p10")); TargetFormats.push_back(FFMS_GetPixFmt("yuv422p10")); TargetFormats.push_back(FFMS_GetPixFmt("yuva422p10")); TargetFormats.push_back(FFMS_GetPixFmt("yuv444p10")); TargetFormats.push_back(FFMS_GetPixFmt("yuva444p10")); TargetFormats.push_back(FFMS_GetPixFmt("gbrp16")); TargetFormats.push_back(FFMS_GetPixFmt("gbrap16")); TargetFormats.push_back(FFMS_GetPixFmt("gray16")); TargetFormats.push_back(FFMS_GetPixFmt("yuva420p")); TargetFormats.push_back(FFMS_GetPixFmt("yuva422p")); TargetFormats.push_back(FFMS_GetPixFmt("yuva444p")); } TargetFormats.push_back(FFMS_GetPixFmt("yuv410p")); TargetFormats.push_back(FFMS_GetPixFmt("yuv411p")); TargetFormats.push_back(FFMS_GetPixFmt("yuv420p")); TargetFormats.push_back(FFMS_GetPixFmt("yuv422p")); TargetFormats.push_back(FFMS_GetPixFmt("yuv444p")); TargetFormats.push_back(FFMS_GetPixFmt("gray8")); TargetFormats.push_back(FFMS_GetPixFmt("yuyv422")); TargetFormats.push_back(FFMS_GetPixFmt("bgra")); // Remove unsupported formats from list so they don't appear as an early termination TargetFormats.erase(std::remove(TargetFormats.begin(), TargetFormats.end(), -1), TargetFormats.end()); TargetFormats.push_back(-1); // PIX_FMT_NV21 is misused as a return value different to the defined ones in the function AVPixelFormat TargetPixelFormat = CSNameToPIXFMT(ConvertToFormatName, FFMS_PIX_FMT(NV21), HighBitDepth); if (TargetPixelFormat == FFMS_PIX_FMT(NONE)) Env->ThrowError("FFVideoSource: Invalid colorspace name specified"); if (TargetPixelFormat != FFMS_PIX_FMT(NV21)) { TargetFormats.clear(); TargetFormats.push_back(TargetPixelFormat); TargetFormats.push_back(-1); } if (ResizeToWidth <= 0) ResizeToWidth = F->EncodedWidth; if (ResizeToHeight <= 0) ResizeToHeight = F->EncodedHeight; int Resizer = ResizerNameToSWSResizer(ResizerName); if (Resizer == 0) Env->ThrowError("FFVideoSource: Invalid resizer name specified"); if (FFMS_SetOutputFormatV2(V, TargetFormats.data(), ResizeToWidth, ResizeToHeight, Resizer, &E)) Env->ThrowError("FFVideoSource: No suitable output format found"); F = FFMS_GetFrame(V, 0, &E); TargetFormats.clear(); TargetFormats.push_back(F->ConvertedPixelFormat); TargetFormats.push_back(-1); // This trick is required to first get the "best" default format and then set only that format as the output if (FFMS_SetOutputFormatV2(V, TargetFormats.data(), ResizeToWidth, ResizeToHeight, Resizer, &E)) Env->ThrowError("FFVideoSource: No suitable output format found"); F = FFMS_GetFrame(V, 0, &E); if (F->ConvertedPixelFormat == FFMS_GetPixFmt("yuvj420p") || F->ConvertedPixelFormat == FFMS_GetPixFmt("yuv420p")) VI.pixel_type = VideoInfo::CS_I420; else if (F->ConvertedPixelFormat == FFMS_GetPixFmt("yuva420p")) VI.pixel_type = VideoInfo::CS_YUVA420; else if (F->ConvertedPixelFormat == FFMS_GetPixFmt("yuvj422p") || F->ConvertedPixelFormat == FFMS_GetPixFmt("yuv422p")) VI.pixel_type = VideoInfo::CS_YV16; else if (F->ConvertedPixelFormat == FFMS_GetPixFmt("yuva422p")) VI.pixel_type = VideoInfo::CS_YUVA422; else if (F->ConvertedPixelFormat == FFMS_GetPixFmt("yuvj444p") || F->ConvertedPixelFormat == FFMS_GetPixFmt("yuv444p")) VI.pixel_type = VideoInfo::CS_YV24; else if (F->ConvertedPixelFormat == FFMS_GetPixFmt("yuva444p")) VI.pixel_type = VideoInfo::CS_YUVA444; else if (F->ConvertedPixelFormat == FFMS_GetPixFmt("yuv411p")) VI.pixel_type = VideoInfo::CS_YV411; else if (F->ConvertedPixelFormat == FFMS_GetPixFmt("yuv410p")) VI.pixel_type = VideoInfo::CS_YUV9; else if (F->ConvertedPixelFormat == FFMS_GetPixFmt("gray8")) VI.pixel_type = VideoInfo::CS_Y8; else if (F->ConvertedPixelFormat == FFMS_GetPixFmt("yuyv422")) VI.pixel_type = VideoInfo::CS_YUY2; else if (F->ConvertedPixelFormat == FFMS_GetPixFmt("rgb32")) VI.pixel_type = VideoInfo::CS_BGR32; else if (F->ConvertedPixelFormat == FFMS_GetPixFmt("bgr24")) VI.pixel_type = VideoInfo::CS_BGR24; else if (F->ConvertedPixelFormat == FFMS_GetPixFmt("yuv420p16")) VI.pixel_type = VideoInfo::CS_YUV420P16; else if (F->ConvertedPixelFormat == FFMS_GetPixFmt("yuva420p16")) VI.pixel_type = VideoInfo::CS_YUVA420P16; else if (F->ConvertedPixelFormat == FFMS_GetPixFmt("yuv422p16")) VI.pixel_type = VideoInfo::CS_YUV422P16; else if (F->ConvertedPixelFormat == FFMS_GetPixFmt("yuva422p16")) VI.pixel_type = VideoInfo::CS_YUVA422P16; else if (F->ConvertedPixelFormat == FFMS_GetPixFmt("yuv444p16")) VI.pixel_type = VideoInfo::CS_YUV444P16; else if (F->ConvertedPixelFormat == FFMS_GetPixFmt("yuva444p16")) VI.pixel_type = VideoInfo::CS_YUVA444P16; else if (F->ConvertedPixelFormat == FFMS_GetPixFmt("yuv420p10")) VI.pixel_type = VideoInfo::CS_YUV420P10; else if (F->ConvertedPixelFormat == FFMS_GetPixFmt("yuva420p10")) VI.pixel_type = VideoInfo::CS_YUVA420P10; else if (F->ConvertedPixelFormat == FFMS_GetPixFmt("yuv422p10")) VI.pixel_type = VideoInfo::CS_YUV422P10; else if (F->ConvertedPixelFormat == FFMS_GetPixFmt("yuva422p10")) VI.pixel_type = VideoInfo::CS_YUVA422P10; else if (F->ConvertedPixelFormat == FFMS_GetPixFmt("yuv444p10")) VI.pixel_type = VideoInfo::CS_YUV444P10; else if (F->ConvertedPixelFormat == FFMS_GetPixFmt("yuva444p10")) VI.pixel_type = VideoInfo::CS_YUVA444P10; else if (F->ConvertedPixelFormat == FFMS_GetPixFmt("gbrp16")) VI.pixel_type = VideoInfo::CS_RGBP16; else if (F->ConvertedPixelFormat == FFMS_GetPixFmt("gbrap16")) VI.pixel_type = VideoInfo::CS_RGBAP16; else if (F->ConvertedPixelFormat == FFMS_GetPixFmt("gray16")) VI.pixel_type = VideoInfo::CS_Y16; else Env->ThrowError("FFVideoSource: No suitable output format found"); if (RFFMode > 0 && ResizeToHeight != F->EncodedHeight) Env->ThrowError("FFVideoSource: Vertical scaling not allowed in RFF mode"); if (RFFMode > 0 && TargetPixelFormat != FFMS_PIX_FMT(NV21)) Env->ThrowError("FFVideoSource: Only the default output colorspace can be used in RFF mode"); // set color information variables Env->SetVar(Env->Sprintf("%s%s", this->VarPrefix, "FFCOLOR_SPACE"), F->ColorSpace); Env->SetVar(Env->Sprintf("%s%s", this->VarPrefix, "FFCOLOR_RANGE"), F->ColorRange); if (VP->TopFieldFirst) VI.image_type = VideoInfo::IT_TFF; else VI.image_type = VideoInfo::IT_BFF; VI.width = F->ScaledWidth; VI.height = F->ScaledHeight; // Crop to obey subsampling width/height requirements VI.width -= VI.width % (1 << GetSubSamplingW(VI)); VI.height -= VI.height % (1 << (GetSubSamplingH(VI) + (RFFMode > 0 ? 1 : 0))); }
SWScale::SWScale(avxsynth::PClip Child, int ResizeToWidth, int ResizeToHeight, const char *ResizerName, const char *ConvertToFormatName, avxsynth::IScriptEnvironment *Env) : avxsynth::GenericVideoFilter(Child) { Context = NULL; OrigWidth = vi.width; OrigHeight = vi.height; FlipOutput = vi.IsYUV(); PixelFormat ConvertFromFormat = PIX_FMT_NONE; if (vi.IsYV12()) ConvertFromFormat = PIX_FMT_YUV420P; if (vi.IsYUY2()) ConvertFromFormat = PIX_FMT_YUYV422; if (vi.IsRGB24()) ConvertFromFormat = PIX_FMT_BGR24; if (vi.IsRGB32()) ConvertFromFormat = PIX_FMT_RGB32; if (ResizeToHeight <= 0) ResizeToHeight = OrigHeight; else vi.height = ResizeToHeight; if (ResizeToWidth <= 0) ResizeToWidth = OrigWidth; else vi.width = ResizeToWidth; PixelFormat ConvertToFormat = CSNameToPIXFMT(ConvertToFormatName, ConvertFromFormat); if (ConvertToFormat == PIX_FMT_NONE) Env->ThrowError("SWScale: Invalid colorspace specified (%s)", ConvertToFormatName); switch (ConvertToFormat) { case PIX_FMT_YUV420P: vi.pixel_type = avxsynth::VideoInfo::CS_I420; break; case PIX_FMT_YUYV422: vi.pixel_type = avxsynth::VideoInfo::CS_YUY2; break; case PIX_FMT_BGR24: vi.pixel_type = avxsynth::VideoInfo::CS_BGR24; break; case PIX_FMT_RGB32: vi.pixel_type = avxsynth::VideoInfo::CS_BGR32; break; case PIX_FMT_NONE: case PIX_FMT_RGB24: case PIX_FMT_YUV422P: case PIX_FMT_YUV444P: case PIX_FMT_YUV410P: case PIX_FMT_YUV411P: case PIX_FMT_GRAY8: case PIX_FMT_MONOWHITE: case PIX_FMT_MONOBLACK: case PIX_FMT_PAL8: case PIX_FMT_YUVJ420P: case PIX_FMT_YUVJ422P: case PIX_FMT_YUVJ444P: case PIX_FMT_XVMC_MPEG2_MC: case PIX_FMT_XVMC_MPEG2_IDCT: case PIX_FMT_UYVY422: case PIX_FMT_UYYVYY411: case PIX_FMT_BGR8: case PIX_FMT_BGR4: case PIX_FMT_BGR4_BYTE: case PIX_FMT_RGB8: case PIX_FMT_RGB4: case PIX_FMT_RGB4_BYTE: case PIX_FMT_NV12: case PIX_FMT_NV21: case PIX_FMT_ARGB: case PIX_FMT_RGBA: case PIX_FMT_ABGR: case PIX_FMT_GRAY16BE: case PIX_FMT_GRAY16LE: case PIX_FMT_YUV440P: case PIX_FMT_YUVJ440P: case PIX_FMT_YUVA420P: case PIX_FMT_VDPAU_H264: case PIX_FMT_VDPAU_MPEG1: case PIX_FMT_VDPAU_MPEG2: case PIX_FMT_VDPAU_WMV3: case PIX_FMT_VDPAU_VC1: case PIX_FMT_RGB48BE: case PIX_FMT_RGB48LE: case PIX_FMT_RGB565BE: case PIX_FMT_RGB565LE: case PIX_FMT_RGB555BE: case PIX_FMT_RGB555LE: case PIX_FMT_BGR565BE: case PIX_FMT_BGR565LE: case PIX_FMT_BGR555BE: case PIX_FMT_BGR555LE: case PIX_FMT_VAAPI_MOCO: case PIX_FMT_VAAPI_IDCT: case PIX_FMT_VAAPI_VLD: case PIX_FMT_YUV420P16LE: case PIX_FMT_YUV420P16BE: case PIX_FMT_YUV422P16LE: case PIX_FMT_YUV422P16BE: case PIX_FMT_YUV444P16LE: case PIX_FMT_YUV444P16BE: case PIX_FMT_VDPAU_MPEG4: case PIX_FMT_DXVA2_VLD: case PIX_FMT_RGB444LE: case PIX_FMT_RGB444BE: case PIX_FMT_BGR444LE: case PIX_FMT_BGR444BE: case PIX_FMT_Y400A: case PIX_FMT_BGR48BE: case PIX_FMT_BGR48LE: case PIX_FMT_YUV420P9BE: case PIX_FMT_YUV420P9LE: case PIX_FMT_YUV420P10BE: case PIX_FMT_YUV420P10LE: case PIX_FMT_YUV422P10BE: case PIX_FMT_YUV422P10LE: case PIX_FMT_YUV444P9BE: case PIX_FMT_YUV444P9LE: case PIX_FMT_YUV444P10BE: case PIX_FMT_YUV444P10LE: case PIX_FMT_NB: default: break; } FlipOutput ^= vi.IsYUV(); int Resizer = ResizerNameToSWSResizer(ResizerName); if (Resizer == 0) Env->ThrowError("SWScale: Invalid resizer specified (%s)", ResizerName); if (ConvertToFormat == PIX_FMT_YUV420P && vi.height & 1) Env->ThrowError("SWScale: mod 2 output height required"); if ((ConvertToFormat == PIX_FMT_YUV420P || ConvertToFormat == PIX_FMT_YUYV422) && vi.width & 1) Env->ThrowError("SWScale: mod 2 output width required"); Context = FFGetSwsContext(OrigWidth, OrigHeight, ConvertFromFormat, vi.width, vi.height, ConvertToFormat, AvisynthToSWSCPUFlags(Env->GetCPUFlags()) | Resizer, FFGetSwsAssumedColorSpace(OrigWidth, OrigHeight)); if (Context == NULL) Env->ThrowError("SWScale: Context creation failed"); }
void AvisynthVideoSource::InitOutputFormat( int ResizeToWidth, int ResizeToHeight, const char *ResizerName, const char *ConvertToFormatName, IScriptEnvironment *Env) { char ErrorMsg[1024]; FFMS_ErrorInfo E; E.Buffer = ErrorMsg; E.BufferSize = sizeof(ErrorMsg); const FFMS_VideoProperties *VP = FFMS_GetVideoProperties(V); const FFMS_Frame *F = FFMS_GetFrame(V, 0, &E); if (!F) Env->ThrowError("FFVideoSource: %s", E.Buffer); int TargetFormats[4]; TargetFormats[0] = FFMS_GetPixFmt("yuv420p"); TargetFormats[1] = FFMS_GetPixFmt("yuyv422"); TargetFormats[2] = FFMS_GetPixFmt("bgra"); TargetFormats[3] = -1; // PIX_FMT_NV21 is misused as a return value different to the defined ones in the function PixelFormat TargetPixelFormat = CSNameToPIXFMT(ConvertToFormatName, PIX_FMT_NV21); if (TargetPixelFormat == PIX_FMT_NONE) Env->ThrowError("FFVideoSource: Invalid colorspace name specified"); if (TargetPixelFormat != PIX_FMT_NV21) { TargetFormats[0] = TargetPixelFormat; TargetFormats[1] = -1; } if (ResizeToWidth <= 0) ResizeToWidth = F->EncodedWidth; if (ResizeToHeight <= 0) ResizeToHeight = F->EncodedHeight; int Resizer = ResizerNameToSWSResizer(ResizerName); if (Resizer == 0) Env->ThrowError("FFVideoSource: Invalid resizer name specified"); if (FFMS_SetOutputFormatV2(V, TargetFormats, ResizeToWidth, ResizeToHeight, Resizer, &E)) Env->ThrowError("FFVideoSource: No suitable output format found"); F = FFMS_GetFrame(V, 0, &E); TargetFormats[0] = F->ConvertedPixelFormat; TargetFormats[1] = -1; // This trick is required to first get the "best" default format and then set only that format as the output if (FFMS_SetOutputFormatV2(V, TargetFormats, ResizeToWidth, ResizeToHeight, Resizer, &E)) Env->ThrowError("FFVideoSource: No suitable output format found"); F = FFMS_GetFrame(V, 0, &E); if (F->ConvertedPixelFormat == FFMS_GetPixFmt("yuvj420p") || F->ConvertedPixelFormat == FFMS_GetPixFmt("yuv420p")) VI.pixel_type = VideoInfo::CS_I420; else if (F->ConvertedPixelFormat == FFMS_GetPixFmt("yuyv422")) VI.pixel_type = VideoInfo::CS_YUY2; else if (F->ConvertedPixelFormat == FFMS_GetPixFmt("rgb32")) VI.pixel_type = VideoInfo::CS_BGR32; else if (F->ConvertedPixelFormat == FFMS_GetPixFmt("bgr24")) VI.pixel_type = VideoInfo::CS_BGR24; else Env->ThrowError("FFVideoSource: No suitable output format found"); if (RFFMode > 0 && ResizeToHeight != F->EncodedHeight) Env->ThrowError("FFVideoSource: Vertical scaling not allowed in RFF mode"); if (RFFMode > 0 && TargetPixelFormat != PIX_FMT_NV21) Env->ThrowError("FFVideoSource: Only the default output colorspace can be used in RFF mode"); // set color information variables Env->SetVar(Env->Sprintf("%s%s", this->VarPrefix, "FFCOLOR_SPACE"), F->ColorSpace); Env->SetVar(Env->Sprintf("%s%s", this->VarPrefix, "FFCOLOR_RANGE"), F->ColorRange); if (VP->TopFieldFirst) VI.image_type = VideoInfo::IT_TFF; else VI.image_type = VideoInfo::IT_BFF; VI.width = F->ScaledWidth; VI.height = F->ScaledHeight; // Crop to obey avisynth's even width/height requirements if (VI.pixel_type == VideoInfo::CS_I420) { VI.height -= VI.height & 1; VI.width -= VI.width & 1; } if (VI.pixel_type == VideoInfo::CS_YUY2) { VI.width -= VI.width & 1; } if (RFFMode > 0) { VI.height -= VI.height & 1; } }