diff --git a/aegisub/video_frame.cpp b/aegisub/video_frame.cpp index e5c4ed84f..97917efc4 100644 --- a/aegisub/video_frame.cpp +++ b/aegisub/video_frame.cpp @@ -45,8 +45,8 @@ AegiVideoFrame::AegiVideoFrame() { for (int i=0;i<4;i++) { data[i] = NULL; pitch[i] = 0; - memSize[i] = 0; } + memSize = 0; w = 0; h = 0; format = FORMAT_RGB24; @@ -78,18 +78,24 @@ AegiVideoFrame::AegiVideoFrame(int width,int height,VideoFrameFormat fmt) { //////////// // Allocate void AegiVideoFrame::Allocate() { - for (int i=0;i<4;i++) { - // Get size - int height = h; - if (format == FORMAT_YV12 && i > 0) height/=2; - unsigned int size = pitch[i]*height; + // Get size + int height = h; + unsigned int size = pitch[0]*height; + if (format == FORMAT_YV12) size = size * 3 / 2; + else size = size * GetBpp(); - // Reallocate, if necessary - if (memSize[i] != size) { - if (cppAlloc) delete[] data[i]; - else free(data[i]); - data[i] = new unsigned char[size]; - memSize[i] = size; + // Reallocate, if necessary + if (memSize != size) { + if (cppAlloc) delete[] data[0]; + else free(data[0]); + data[0] = new unsigned char[size]; + for (int i=1;i<4;i++) data[i] = NULL; + memSize = size; + + // Planar + if (format == FORMAT_YV12) { + data[1] = data[0] + (pitch[0]*height); + data[2] = data[0] + (pitch[0]*height*5/4); } } @@ -100,14 +106,13 @@ void AegiVideoFrame::Allocate() { ///////// // Clear void AegiVideoFrame::Clear() { + if (cppAlloc) delete[] data[0]; + else free(data[0]); for (int i=0;i<4;i++) { - if (data[i]) { - if (cppAlloc) delete[] data[i]; - else free(data[i]); - data[i] = NULL; - } + data[i] = NULL; pitch[i] = 0; } + memSize = 0; w = 0; h = 0; format = FORMAT_RGB24; @@ -125,9 +130,7 @@ void AegiVideoFrame::CopyFrom(const AegiVideoFrame &source) { format = source.format; for (int i=0;i<4;i++) pitch[i] = source.pitch[i]; Allocate(); - for (int i=0;i<4;i++) { - memcpy(data[i],source.data[i],memSize[i]); - } + memcpy(data[0],source.data[0],memSize); flipped = source.flipped; invertChannels = source.invertChannels; } diff --git a/aegisub/video_frame.h b/aegisub/video_frame.h index ded1911f9..d5f96df78 100644 --- a/aegisub/video_frame.h +++ b/aegisub/video_frame.h @@ -51,7 +51,7 @@ enum VideoFrameFormat { // Video Frame class class AegiVideoFrame { private: - unsigned int memSize[4]; + unsigned int memSize; public: unsigned char *data[4]; // Pointers to the data planes. Interleaved formats only use data[0] diff --git a/aegisub/video_provider_dshow.cpp b/aegisub/video_provider_dshow.cpp index b67d19f61..2074e10ee 100644 --- a/aegisub/video_provider_dshow.cpp +++ b/aegisub/video_provider_dshow.cpp @@ -429,14 +429,14 @@ void DirectShowVideoProvider::ReadFrame(long long timestamp, unsigned format, un // Interleaved else { - unsigned int datalen = stride*height; - df->frame.Allocate(); - memcpy(df->frame.data[0],src,datalen); - // 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; + + unsigned int datalen = stride*height; + df->frame.Allocate(); + memcpy(df->frame.data[0],src,datalen); } }