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.
This commit is contained in:
parent
e7f2dc00f7
commit
d1762c5270
17 changed files with 52 additions and 185 deletions
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -85,7 +85,7 @@ void DVDSubtitleFormat::GetSubPictureList(std::vector<SubPicture> &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
|
||||
|
|
|
@ -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) {
|
||||
GLenum format;
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
||||
// 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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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<CachedFrame>::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);
|
||||
}
|
||||
|
||||
|
|
|
@ -60,7 +60,6 @@ private:
|
|||
VideoProvider *master;
|
||||
unsigned int cacheMax;
|
||||
std::list<CachedFrame> 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();
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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; };
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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)
|
||||
|
@ -297,31 +298,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);
|
||||
if (SrcFrame == NULL) {
|
||||
|
@ -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;
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
|
|
@ -56,8 +56,6 @@ private:
|
|||
std::vector<int> 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();
|
||||
|
||||
|
|
|
@ -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,40 +356,20 @@ 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;
|
||||
|
||||
tmp_frame.format = src_fmt;
|
||||
|
@ -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);
|
||||
|
||||
tmp_frame.Clear();
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
Loading…
Reference in a new issue