From d1762c5270260efa907f436fd2e530c6061b2616 Mon Sep 17 00:00:00 2001 From: Karl Blomster Date: Mon, 20 Jul 2009 03:50:25 +0000 Subject: [PATCH] The Great Colorspace Reworking of '09, part 2 of ???: change all video providers to always output RGB32, and remove the formatMask parameter of GetFrame(). This may break the dshow video provider but I have no way of testing it and AFAIK nobody else does either. If someone actually uses it, they can fix it themselves. Updates #926. Originally committed to SVN as r3185. --- aegisub/src/include/aegisub/video_provider.h | 2 +- aegisub/src/subs_preview.cpp | 2 +- aegisub/src/subtitle_format_dvd.cpp | 2 +- aegisub/src/video_context.cpp | 35 ++----------- aegisub/src/video_frame.h | 18 ++++--- aegisub/src/video_provider_avs.cpp | 28 ++--------- aegisub/src/video_provider_avs.h | 2 +- aegisub/src/video_provider_cache.cpp | 18 ++----- aegisub/src/video_provider_cache.h | 3 +- aegisub/src/video_provider_dshow.cpp | 22 +------- aegisub/src/video_provider_dshow.h | 2 +- aegisub/src/video_provider_dummy.cpp | 2 +- aegisub/src/video_provider_dummy.h | 2 +- aegisub/src/video_provider_ffmpegsource.cpp | 53 ++++---------------- aegisub/src/video_provider_ffmpegsource.h | 4 +- aegisub/src/video_provider_yuv4mpeg.cpp | 40 +++------------ aegisub/src/video_provider_yuv4mpeg.h | 2 +- 17 files changed, 52 insertions(+), 185 deletions(-) diff --git a/aegisub/src/include/aegisub/video_provider.h b/aegisub/src/include/aegisub/video_provider.h index 5bd70c2ba..8a7a953be 100644 --- a/aegisub/src/include/aegisub/video_provider.h +++ b/aegisub/src/include/aegisub/video_provider.h @@ -52,7 +52,7 @@ public: virtual ~VideoProvider() {} // Override this method to actually get frames - virtual const AegiVideoFrame GetFrame(int n, int formatMask)=0; + virtual const AegiVideoFrame GetFrame(int n)=0; // Override the following methods to get video information: virtual int GetPosition()=0; // Get the number of the last frame loaded diff --git a/aegisub/src/subs_preview.cpp b/aegisub/src/subs_preview.cpp index 122879ed2..d640ff647 100644 --- a/aegisub/src/subs_preview.cpp +++ b/aegisub/src/subs_preview.cpp @@ -140,7 +140,7 @@ void SubtitlesPreview::UpdateBitmap(int w,int h) { // Get AegiVideoFrame if (!vid) vid = new DummyVideoProvider(0.0,10,w,h,backColour,true); AegiVideoFrame frame; - frame.CopyFrom(vid->GetFrame(0,FORMAT_RGB32)); + frame.CopyFrom(vid->GetFrame(0)); // Try to get subtitles provider SubtitlesProvider *provider = NULL; diff --git a/aegisub/src/subtitle_format_dvd.cpp b/aegisub/src/subtitle_format_dvd.cpp index 705c329e1..779dd3cc1 100644 --- a/aegisub/src/subtitle_format_dvd.cpp +++ b/aegisub/src/subtitle_format_dvd.cpp @@ -85,7 +85,7 @@ void DVDSubtitleFormat::GetSubPictureList(std::vector &pics) { int w = 720; int h = 480; VideoProvider *video = new DummyVideoProvider(10,1,w,h,wxColour(255,0,0),false); - AegiVideoFrame srcFrame = video->GetFrame(0,FORMAT_RGB32); + AegiVideoFrame srcFrame = video->GetFrame(0); delete video; // Count and index lines diff --git a/aegisub/src/video_context.cpp b/aegisub/src/video_context.cpp index ff3249cb8..d6794d4cd 100644 --- a/aegisub/src/video_context.cpp +++ b/aegisub/src/video_context.cpp @@ -492,11 +492,8 @@ AegiVideoFrame VideoContext::GetFrame(int n,bool raw) { // Current frame if -1 if (n == -1) n = frame_n; - // Get available formats - int formats = FORMAT_RGB32; - // Get frame - AegiVideoFrame frame = provider->GetFrame(n,formats); + AegiVideoFrame frame = provider->GetFrame(n); // Raster subtitles if available/necessary if (!raw && subsProvider) { @@ -532,18 +529,9 @@ GLuint VideoContext::GetFrameAsTexture(int n) { if (glGetError() != 0) throw _T("Error enabling texture."); // Image type - GLenum format = GL_LUMINANCE; - if (frame.format == FORMAT_RGB32) { - if (frame.invertChannels) format = GL_BGRA_EXT; - else format = GL_RGBA; - } - else if (frame.format == FORMAT_RGB24) { - if (frame.invertChannels) format = GL_BGR_EXT; - else format = GL_RGB; - } - else if (frame.format == FORMAT_YV12) { - format = GL_LUMINANCE; - } + GLenum format; + if (frame.invertChannels) format = GL_BGRA_EXT; + else format = GL_RGBA; isInverted = frame.flipped; if (lastTex == 0) { @@ -569,7 +557,6 @@ GLuint VideoContext::GetFrameAsTexture(int n) { // Allocate texture int height = frame.h; - if (frame.format == FORMAT_YV12) height = height * 3 / 2; int tw = SmallestPowerOf2(MAX(frame.pitch[0]/frame.GetBpp(0),frame.pitch[1]+frame.pitch[2])); int th = SmallestPowerOf2(height); glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA8,tw,th,0,format,GL_UNSIGNED_BYTE,NULL); @@ -599,20 +586,6 @@ GLuint VideoContext::GetFrameAsTexture(int n) { glTexSubImage2D(GL_TEXTURE_2D,0,0,0,frame.pitch[0]/frame.GetBpp(0),frame.h,format,GL_UNSIGNED_BYTE,frame.data[0]); if (glGetError() != 0) throw _T("Error uploading primary plane"); - // UV planes for YV12 - if (frame.format == FORMAT_YV12) { - int u = 1; - int v = 2; - if (frame.invertChannels) { - u = 2; - v = 1; - } - glTexSubImage2D(GL_TEXTURE_2D,0,0,frame.h,frame.pitch[1],frame.h/2,format,GL_UNSIGNED_BYTE,frame.data[u]); - if (glGetError() != 0) throw _T("Error uploading U plane."); - glTexSubImage2D(GL_TEXTURE_2D,0,frame.pitch[1],frame.h,frame.pitch[2],frame.h/2,format,GL_UNSIGNED_BYTE,frame.data[v]); - if (glGetError() != 0) throw _T("Error uploadinv V plane."); - } - // Return texture number return lastTex; } diff --git a/aegisub/src/video_frame.h b/aegisub/src/video_frame.h index 20971db1e..085844f2b 100644 --- a/aegisub/src/video_frame.h +++ b/aegisub/src/video_frame.h @@ -40,12 +40,16 @@ ////////////////////// // Video Frame format +// All formats use 8 bits per sample. enum VideoFrameFormat { - FORMAT_NONE = 0, - FORMAT_RGB24 = 1, - FORMAT_RGB32 = 2, - FORMAT_YUY2 = 4, - FORMAT_YV12 = 8 + FORMAT_NONE = 0x0000, + FORMAT_RGB24 = 0x0001, // RGB, interleaved + FORMAT_RGB32 = 0x0002, // RGBA, interleaved + FORMAT_YUY2 = 0x0004, // YCbCr 4:2:2, planar + FORMAT_YV12 = 0x0008, // YCbCr 4:2:0, planar + FORMAT_YUV444 = 0x0010, // YCbCr 4:4:4, planar + FORMAT_YUV444A = 0x0020, // YCbCr 4:4:4 plus alpha, planar + FORMAT_YUVMONO = 0x0040, // Y only (greyscale) }; @@ -58,13 +62,13 @@ private: public: unsigned char *data[4]; // Pointers to the data planes. Interleaved formats only use data[0] - VideoFrameFormat format; // Data format, one of FORMAT_RGB24, FORMAT_RGB32, FORMAT_YUY2 and FORMAT_YV12 + VideoFrameFormat format; // Data format unsigned int w; // Width in pixels unsigned int h; // Height in pixels unsigned int pitch[4]; // Pitch, that is, the number of bytes used by each row. bool flipped; // First row is actually the bottom one - bool invertChannels; // Invert Red and Blue channels or U and V planes + bool invertChannels; // Swap Red and Blue channels or U and V planes (controls RGB versus BGR ordering etc) bool cppAlloc; // Allocated with C++'s "new" operator, instead of "malloc" AegiVideoFrame(); diff --git a/aegisub/src/video_provider_avs.cpp b/aegisub/src/video_provider_avs.cpp index 66528bf7f..49d202eb8 100644 --- a/aegisub/src/video_provider_avs.cpp +++ b/aegisub/src/video_provider_avs.cpp @@ -341,7 +341,7 @@ PClip AvisynthVideoProvider::OpenVideo(Aegisub::String _filename, bool mpeg2dec3 //////////////////////// // Actually get a frame -const AegiVideoFrame AvisynthVideoProvider::GetFrame(int _n,int formatMask) { +const AegiVideoFrame AvisynthVideoProvider::GetFrame(int _n) { // Transform n if overriden int n = _n; if (frameTime.Count()) { @@ -365,25 +365,12 @@ const AegiVideoFrame AvisynthVideoProvider::GetFrame(int _n,int formatMask) { final.invertChannels = false; // Format - if (vi.IsRGB32()) { - final.format = FORMAT_RGB32; - final.flipped = true; - final.invertChannels = true; - } - else if (vi.IsRGB24()) { - final.format = FORMAT_RGB24; - final.flipped = true; - final.invertChannels = true; - } - else if (vi.IsYV12()) final.format = FORMAT_YV12; - else if (vi.IsYUY2()) final.format = FORMAT_YUY2; + final.format = FORMAT_RGB32; + final.flipped = true; + final.invertChannels = true; // Set size properties - int uvpitch = 0; - if (final.format == FORMAT_YV12) uvpitch = frame->GetPitch(PLANAR_U); final.pitch[0] = frame->GetPitch(); - final.pitch[1] = uvpitch; - final.pitch[2] = uvpitch; final.w = frame->GetRowSize() / Bpp; final.h = frame->GetHeight(); @@ -393,13 +380,6 @@ const AegiVideoFrame AvisynthVideoProvider::GetFrame(int _n,int formatMask) { // Copy memcpy(final.data[0],frame->GetReadPtr(),final.pitch[0] * final.h); - // Copy second and third planes for YV12 - if (final.format == FORMAT_YV12) { - int uvh = frame->GetHeight(PLANAR_U); - memcpy(final.data[1],frame->GetReadPtr(PLANAR_U),uvpitch * uvh); - memcpy(final.data[2],frame->GetReadPtr(PLANAR_V),uvpitch * uvh); - } - // Set last number last_fnum = n; return final; diff --git a/aegisub/src/video_provider_avs.h b/aegisub/src/video_provider_avs.h index 9f4c2085f..a46b9d7de 100644 --- a/aegisub/src/video_provider_avs.h +++ b/aegisub/src/video_provider_avs.h @@ -73,7 +73,7 @@ public: AvisynthVideoProvider(Aegisub::String _filename); ~AvisynthVideoProvider(); - const AegiVideoFrame GetFrame(int n,int formatMask); + const AegiVideoFrame GetFrame(int n); void GetFloatFrame(float* Buffer, int n); // properties diff --git a/aegisub/src/video_provider_cache.cpp b/aegisub/src/video_provider_cache.cpp index ca6ed778a..9ff58b0b0 100644 --- a/aegisub/src/video_provider_cache.cpp +++ b/aegisub/src/video_provider_cache.cpp @@ -55,13 +55,12 @@ VideoProviderCache::VideoProviderCache(VideoProvider *parent) { VideoProviderCache::~VideoProviderCache() { delete master; ClearCache(); - tempRGBFrame.Clear(); } ///////////// // Get frame -const AegiVideoFrame VideoProviderCache::GetFrame(int n,int format) { +const AegiVideoFrame VideoProviderCache::GetFrame(int n) { // See if frame is cached CachedFrame cached; for (std::list::iterator cur=cache.begin();cur!=cache.end();cur++) { @@ -74,20 +73,9 @@ const AegiVideoFrame VideoProviderCache::GetFrame(int n,int format) { } // Not cached, retrieve it - const AegiVideoFrame frame = master->GetFrame(n, format); + const AegiVideoFrame frame = master->GetFrame(n); const AegiVideoFrame *srcFrame = &frame; - // Convert to compatible format - if (!(frame.format & format)) { - if (format & FORMAT_RGB32) tempRGBFrame.format = FORMAT_RGB32; - else throw _T("Unable to negotiate video frame format."); - tempRGBFrame.w = frame.w; - tempRGBFrame.h = frame.h; - tempRGBFrame.pitch[0] = frame.w * 4; - tempRGBFrame.ConvertFrom(frame); - srcFrame = &tempRGBFrame; - } - // Cache frame pos = n; Cache(n,*srcFrame); @@ -98,7 +86,7 @@ const AegiVideoFrame VideoProviderCache::GetFrame(int n,int format) { //////////////// // Get as float void VideoProviderCache::GetFloatFrame(float* buffer, int n) { - const AegiVideoFrame frame = GetFrame(n,FORMAT_RGB32); + const AegiVideoFrame frame = GetFrame(n); frame.GetFloat(buffer); } diff --git a/aegisub/src/video_provider_cache.h b/aegisub/src/video_provider_cache.h index d2bda6339..6e21a1d83 100644 --- a/aegisub/src/video_provider_cache.h +++ b/aegisub/src/video_provider_cache.h @@ -60,7 +60,6 @@ private: VideoProvider *master; unsigned int cacheMax; std::list cache; - AegiVideoFrame tempRGBFrame; int pos; void Cache(int n,const AegiVideoFrame frame); @@ -74,7 +73,7 @@ protected: public: // Base methods void GetFloatFrame(float* Buffer, int n); // Get frame as float - const AegiVideoFrame GetFrame(int n, int formatMask); + const AegiVideoFrame GetFrame(int n); VideoProviderCache(VideoProvider *master); virtual ~VideoProviderCache(); diff --git a/aegisub/src/video_provider_dshow.cpp b/aegisub/src/video_provider_dshow.cpp index 9c406dbb9..e7e4b6e7f 100644 --- a/aegisub/src/video_provider_dshow.cpp +++ b/aegisub/src/video_provider_dshow.cpp @@ -271,14 +271,6 @@ HRESULT DirectShowVideoProvider::OpenVideo(wxString _filename) { // Get video duration if (FAILED(hr = ms->GetDuration(&duration))) return hr; - // Set pixel type - //switch (type) { - // case IVS_RGB32: m_vi.pixel_type = VideoInfo::CS_BGR32; break; - // case IVS_YUY2: m_vi.pixel_type = VideoInfo::CS_YUY2; break; - // case IVS_YV12: m_vi.pixel_type = VideoInfo::CS_YV12; break; - // default: return E_FAIL; - //} - // Set FPS and frame duration if (defd == 0) defd = 417083; if (fps != 0.0) defd = int64_t (10000000.0 / fps) + 1; @@ -398,21 +390,11 @@ void DirectShowVideoProvider::ReadFrame(int64_t timestamp, unsigned format, unsi df->frame.w = width; df->frame.h = height; df->frame.pitch[0] = stride; - if (format == IVS_YV12) { - df->frame.pitch[1] = stride/2; - df->frame.pitch[2] = stride/2; - } df->frame.cppAlloc = false; df->frame.invertChannels = true; // Set format - if (format == IVS_RGB24) df->frame.format = FORMAT_RGB24; - else if (format == IVS_RGB32) df->frame.format = FORMAT_RGB32; - else if (format == IVS_YV12) { - df->frame.format = FORMAT_YV12; - df->frame.invertChannels = true; - } - else if (format == IVS_YUY2) df->frame.format = FORMAT_YUY2; + df->frame.format = FORMAT_RGB32; // Allocate and copy data df->frame.Allocate(); @@ -473,7 +455,7 @@ int DirectShowVideoProvider::NextFrame(DF &df,int &_fn) { ///////////// // Get frame -const AegiVideoFrame DirectShowVideoProvider::GetFrame(int n,int formatMask) { +const AegiVideoFrame DirectShowVideoProvider::GetFrame(int n) { // Normalize frame number if (n >= (signed) num_frames) n = num_frames-1; if (n < 0) n = 0; diff --git a/aegisub/src/video_provider_dshow.h b/aegisub/src/video_provider_dshow.h index 536ab3f76..47a12b216 100644 --- a/aegisub/src/video_provider_dshow.h +++ b/aegisub/src/video_provider_dshow.h @@ -110,7 +110,7 @@ public: void RefreshSubtitles(); - const AegiVideoFrame GetFrame(int n, int formatMask); + const AegiVideoFrame GetFrame(int n); void GetFloatFrame(float* Buffer, int n); int GetPosition() { return last_fnum; }; diff --git a/aegisub/src/video_provider_dummy.cpp b/aegisub/src/video_provider_dummy.cpp index 70ff5a653..d09a04f7e 100644 --- a/aegisub/src/video_provider_dummy.cpp +++ b/aegisub/src/video_provider_dummy.cpp @@ -206,7 +206,7 @@ wxString DummyVideoProvider::MakeFilename(double fps, int frames, int _width, in ///////////// // Get frame -const AegiVideoFrame DummyVideoProvider::GetFrame(int n,int formatMask) { +const AegiVideoFrame DummyVideoProvider::GetFrame(int n) { lastFrame = n; return frame; } diff --git a/aegisub/src/video_provider_dummy.h b/aegisub/src/video_provider_dummy.h index 6958e956f..a69c25460 100644 --- a/aegisub/src/video_provider_dummy.h +++ b/aegisub/src/video_provider_dummy.h @@ -64,7 +64,7 @@ public: DummyVideoProvider(double fps, int frames, int _width, int _height, const wxColour &colour, bool pattern); ~DummyVideoProvider(); - const AegiVideoFrame GetFrame(int n, int formatMask); + const AegiVideoFrame GetFrame(int n); static wxString MakeFilename(double fps, int frames, int _width, int _height, const wxColour &colour, bool pattern); int GetPosition(); diff --git a/aegisub/src/video_provider_ffmpegsource.cpp b/aegisub/src/video_provider_ffmpegsource.cpp index 072a6848e..56bb9beec 100644 --- a/aegisub/src/video_provider_ffmpegsource.cpp +++ b/aegisub/src/video_provider_ffmpegsource.cpp @@ -70,8 +70,6 @@ FFmpegSourceVideoProvider::FFmpegSourceVideoProvider(Aegisub::String filename) { // clean up variables VideoSource = NULL; - DstFormat = FFMS_GetPixFmt("none"); - LastDstFormat = FFMS_GetPixFmt("none"); KeyFramesLoaded = false; FrameNumber = -1; MsgSize = sizeof(FFMSErrMsg); @@ -217,6 +215,11 @@ void FFmpegSourceVideoProvider::LoadVideo(Aegisub::String filename) { // load video properties VideoInfo = FFMS_GetVideoProperties(VideoSource); + if (FFMS_SetOutputFormatV(VideoSource, 1 << FFMS_GetPixFmt("bgra"), VideoInfo->Width, VideoInfo->Height, FFMS_RESIZER_BICUBIC, FFMSErrMsg, MsgSize)) { + ErrorMsg.Append(wxString::Format(_T("Failed to set output format: %s"), FFMSErrMsg)); + throw ErrorMsg; + } + // get frame info data FFTrack *FrameData = FFMS_GetTrackFromVideo(VideoSource); if (FrameData == NULL) @@ -268,8 +271,6 @@ void FFmpegSourceVideoProvider::Close() { FFMS_DestroyVideoSource(VideoSource); VideoSource = NULL; - DstFormat = FFMS_GetPixFmt("none"); - LastDstFormat = FFMS_GetPixFmt("none"); KeyFramesLoaded = false; KeyFramesList.clear(); TimecodesVector.clear(); @@ -280,7 +281,7 @@ void FFmpegSourceVideoProvider::Close() { /////////////// // Get frame -const AegiVideoFrame FFmpegSourceVideoProvider::GetFrame(int _n, int FormatType) { +const AegiVideoFrame FFmpegSourceVideoProvider::GetFrame(int _n) { // don't try to seek to insane places int n = _n; if (n < 0) @@ -296,31 +297,6 @@ const AegiVideoFrame FFmpegSourceVideoProvider::GetFrame(int _n, int FormatType) // this is what we'll return eventually AegiVideoFrame &DstFrame = CurFrame; - - // choose output format - if (FormatType & FORMAT_RGB32) { - DstFormat = FFMS_GetPixFmt("bgra"); - DstFrame.format = FORMAT_RGB32; - } else if (FormatType & FORMAT_RGB24) { - DstFormat = FFMS_GetPixFmt("bgr24"); - DstFrame.format = FORMAT_RGB24; - } else if (FormatType & FORMAT_YV12) { - DstFormat = FFMS_GetPixFmt("yuv420p"); - DstFrame.format = FORMAT_YV12; - } else if (FormatType & FORMAT_YUY2) { - DstFormat = FFMS_GetPixFmt("yuyv422"); // may or may not work - DstFrame.format = FORMAT_YUY2; - } else - throw _T("FFmpegSource video provider: upstream provider requested unknown or unsupported pixel format"); - - // requested format was changed since last time we were called, (re)set output format - if (LastDstFormat != DstFormat) { - if (FFMS_SetOutputFormatV(VideoSource, 1 << DstFormat, w, h, FFMS_RESIZER_BICUBIC, FFMSErrMsg, MsgSize)) { - ErrorMsg.Append(wxString::Format(_T("Failed to set output format: %s"), FFMSErrMsg)); - throw ErrorMsg; - } - LastDstFormat = DstFormat; - } // decode frame const FFAVFrame *SrcFrame = FFMS_GetFrame(VideoSource, n, FFMSErrMsg, MsgSize); @@ -330,13 +306,11 @@ const AegiVideoFrame FFmpegSourceVideoProvider::GetFrame(int _n, int FormatType) } // set some properties - DstFrame.w = w; - DstFrame.h = h; + DstFrame.format = FORMAT_RGB32; + DstFrame.w = VideoInfo->Width; + DstFrame.h = VideoInfo->Height; DstFrame.flipped = false; - if (DstFrame.format == FORMAT_RGB32 || DstFrame.format == FORMAT_RGB24) - DstFrame.invertChannels = true; - else - DstFrame.invertChannels = false; + DstFrame.invertChannels = true; // allocate destination for (int i = 0; i < 4; i++) @@ -345,13 +319,6 @@ const AegiVideoFrame FFmpegSourceVideoProvider::GetFrame(int _n, int FormatType) // copy data to destination memcpy(DstFrame.data[0], SrcFrame->Data[0], DstFrame.pitch[0] * DstFrame.h); - // if we're dealing with YUV formats we need to copy the U and V planes as well - if (DstFrame.format == FORMAT_YUY2 || DstFrame.format == FORMAT_YV12) { - // YV12 has half the vertical U/V resolution too because of the subsampling - int UVHeight = DstFrame.format == FORMAT_YUY2 ? DstFrame.h : DstFrame.h / 2; - memcpy(DstFrame.data[1], SrcFrame->Data[1], DstFrame.pitch[1] * UVHeight); - memcpy(DstFrame.data[2], SrcFrame->Data[2], DstFrame.pitch[2] * UVHeight); - } return DstFrame; } diff --git a/aegisub/src/video_provider_ffmpegsource.h b/aegisub/src/video_provider_ffmpegsource.h index e04c5613f..9bbeb14f0 100644 --- a/aegisub/src/video_provider_ffmpegsource.h +++ b/aegisub/src/video_provider_ffmpegsource.h @@ -56,8 +56,6 @@ private: std::vector TimecodesVector; FrameRate Timecodes; - int DstFormat; - int LastDstFormat; AegiVideoFrame CurFrame; char FFMSErrMsg[1024]; @@ -75,7 +73,7 @@ public: FFmpegSourceVideoProvider(Aegisub::String filename); ~FFmpegSourceVideoProvider(); - const AegiVideoFrame GetFrame(int n, int formatType); + const AegiVideoFrame GetFrame(int n); int GetPosition(); int GetFrameCount(); diff --git a/aegisub/src/video_provider_yuv4mpeg.cpp b/aegisub/src/video_provider_yuv4mpeg.cpp index 5407666e9..79af2f648 100644 --- a/aegisub/src/video_provider_yuv4mpeg.cpp +++ b/aegisub/src/video_provider_yuv4mpeg.cpp @@ -346,7 +346,7 @@ int YUV4MPEGVideoProvider::IndexFile() { } -const AegiVideoFrame YUV4MPEGVideoProvider::GetFrame(int n, int desired_fmts) { +const AegiVideoFrame YUV4MPEGVideoProvider::GetFrame(int n) { // don't try to seek to insane places if (n < 0) n = 0; @@ -356,39 +356,19 @@ const AegiVideoFrame YUV4MPEGVideoProvider::GetFrame(int n, int desired_fmts) { cur_fn = n; VideoFrameFormat src_fmt, dst_fmt; + dst_fmt = FORMAT_RGB32; + int uv_width, uv_height; switch (pixfmt) { case Y4M_PIXFMT_420JPEG: case Y4M_PIXFMT_420MPEG2: case Y4M_PIXFMT_420PALDV: - src_fmt = FORMAT_YV12; break; + src_fmt = FORMAT_YV12; uv_width = w / 2; uv_height = h / 2; break; case Y4M_PIXFMT_422: - src_fmt = FORMAT_YUY2; break; + src_fmt = FORMAT_YUY2; uv_width = w / 2; uv_height = h; break; // TODO: add support for more pixel formats default: throw wxString(_T("YUV4MPEG video provider: GetFrame: Unsupported source colorspace")); } - - // TODO: fix this terrible piece of crap and implement colorspace conversions - // (write a function to select best output format) - if ((desired_fmts & FORMAT_YV12) && src_fmt == FORMAT_YV12) - dst_fmt = FORMAT_YV12; - else if ((desired_fmts & FORMAT_YUY2) && src_fmt == FORMAT_YUY2) - dst_fmt = FORMAT_YUY2; - else if ((desired_fmts & FORMAT_RGB32) && src_fmt == FORMAT_YV12) - dst_fmt = FORMAT_RGB32; - else - throw wxString(_T("YUV4MPEG video provider: GetFrame: Upstream video provider requested unknown or unsupported color format")); - - int uv_width, uv_height; - // TODO: ugh, fix this - switch (src_fmt) { - case FORMAT_YV12: - uv_width = w / 2; uv_height = h / 2; break; - case FORMAT_YUY2: - uv_width = w / 2; uv_height = h; break; - default: - throw wxString(_T("YUV4MPEG video provider: GetFrame: sanity check failed")); - } AegiVideoFrame tmp_frame; @@ -415,13 +395,9 @@ const AegiVideoFrame YUV4MPEGVideoProvider::GetFrame(int n, int desired_fmts) { dst_frame.format = dst_fmt; dst_frame.w = w; dst_frame.h = h; - if (dst_fmt == FORMAT_RGB32) { - dst_frame.invertChannels = true; - dst_frame.pitch[0] = w * 4; - dst_frame.ConvertFrom(tmp_frame); - } - else - dst_frame.CopyFrom(tmp_frame); + dst_frame.invertChannels = true; + dst_frame.pitch[0] = w * 4; + dst_frame.ConvertFrom(tmp_frame); tmp_frame.Clear(); diff --git a/aegisub/src/video_provider_yuv4mpeg.h b/aegisub/src/video_provider_yuv4mpeg.h index 0fea5c49e..590290416 100644 --- a/aegisub/src/video_provider_yuv4mpeg.h +++ b/aegisub/src/video_provider_yuv4mpeg.h @@ -121,7 +121,7 @@ public: YUV4MPEGVideoProvider(Aegisub::String filename); ~YUV4MPEGVideoProvider(); - const AegiVideoFrame GetFrame(int n, int formatType); + const AegiVideoFrame GetFrame(int n); int GetPosition(); int GetFrameCount();