From d7a6ca1d7612864f124b248966fff3f62265a9c5 Mon Sep 17 00:00:00 2001 From: Rodrigo Braz Monteiro Date: Sat, 24 Mar 2007 02:07:06 +0000 Subject: [PATCH] ffmpeg provider almost works now Originally committed to SVN as r953. --- aegisub/video_frame.cpp | 29 +++++++++------ aegisub/video_frame.h | 1 + aegisub/video_provider_lavc.cpp | 63 ++++++++++++++++++++++----------- aegisub/video_provider_lavc.h | 2 +- 4 files changed, 64 insertions(+), 31 deletions(-) diff --git a/aegisub/video_frame.cpp b/aegisub/video_frame.cpp index 97917efc4..282558c57 100644 --- a/aegisub/video_frame.cpp +++ b/aegisub/video_frame.cpp @@ -39,9 +39,9 @@ #include "video_frame.h" -/////////////// -// Constructor -AegiVideoFrame::AegiVideoFrame() { +///////// +// Reset +void AegiVideoFrame::Reset() { for (int i=0;i<4;i++) { data[i] = NULL; pitch[i] = 0; @@ -56,14 +56,21 @@ AegiVideoFrame::AegiVideoFrame() { } +/////////////// +// Constructor +AegiVideoFrame::AegiVideoFrame() { + Reset(); +} + + ////////////////// // Create default AegiVideoFrame::AegiVideoFrame(int width,int height,VideoFrameFormat fmt) { - AegiVideoFrame(); + Reset(); format = fmt; w = width; h = height; - pitch[0] = w; + pitch[0] = w * GetBpp(); Allocate(); for (int i=0;i<4;i++) { @@ -80,14 +87,16 @@ AegiVideoFrame::AegiVideoFrame(int width,int height,VideoFrameFormat fmt) { void AegiVideoFrame::Allocate() { // Get size int height = h; - unsigned int size = pitch[0]*height; - if (format == FORMAT_YV12) size = size * 3 / 2; - else size = size * GetBpp(); + unsigned int size; + if (format == FORMAT_YV12) size = pitch[0] * height * 3 / 2; + else size = pitch[0] * height; // Reallocate, if necessary if (memSize != size) { - if (cppAlloc) delete[] data[0]; - else free(data[0]); + if (data[0]) { + 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; diff --git a/aegisub/video_frame.h b/aegisub/video_frame.h index aa4460434..a33603b69 100644 --- a/aegisub/video_frame.h +++ b/aegisub/video_frame.h @@ -52,6 +52,7 @@ enum VideoFrameFormat { class AegiVideoFrame { private: unsigned int memSize; + void Reset(); public: unsigned char *data[4]; // Pointers to the data planes. Interleaved formats only use data[0] diff --git a/aegisub/video_provider_lavc.cpp b/aegisub/video_provider_lavc.cpp index 0d3a56f2b..eea6ffcc9 100644 --- a/aegisub/video_provider_lavc.cpp +++ b/aegisub/video_provider_lavc.cpp @@ -300,19 +300,13 @@ const AegiVideoFrame LAVCVideoProvider::DoGetFrame(int n) { // Return stored frame n = MID(0,n,GetFrameCount()-1); if (n == frameNumber) { - if (!validFrame) { - //curFrame = AVFrameToWX(frame, n); - validFrame = true; - } - //return curFrame; - AegiVideoFrame dummy; - return dummy; + if (!validFrame) validFrame = true; + return curFrame; } // Following frame, just get it if (n == frameNumber+1) { GetNextFrame(); - //wxLogMessage(wxString::Format(_T("%i"),lastDecodeTime)); } // Needs to seek @@ -380,21 +374,50 @@ const AegiVideoFrame LAVCVideoProvider::DoGetFrame(int n) { #endif } - // Bitmap - //wxBitmap bmp; - //if (frame) bmp = AVFrameToWX(frame, n); - //else bmp = wxBitmap(GetWidth(),GetHeight()); + // Get frame + AegiVideoFrame final; + if (frame) { + // Set AegiVideoFrame + PixelFormat format = codecContext->pix_fmt; + unsigned int size = avpicture_get_size(format,codecContext->width,codecContext->height); + final.w = codecContext->width; + final.h = codecContext->height; + final.flipped = false; + final.invertChannels = false; - //// Set current frame - //validFrame = true; - //curFrame = bmp; - //frameNumber = n; + // Set format + switch (format) { + case PIX_FMT_BGR24: final.invertChannels = true; + case PIX_FMT_RGB24: final.format = FORMAT_RGB24; break; + case PIX_FMT_BGR32: final.invertChannels = true; + case PIX_FMT_RGB32: final.format = FORMAT_RGB32; break; + case PIX_FMT_YUYV422: final.format = FORMAT_YUY2; break; + case PIX_FMT_YUV420P: final.format = FORMAT_YV12; break; + } - //// Return - //return curFrame; + // Allocate + final.pitch[0] = final.w * final.GetBpp(); + final.Allocate(); - AegiVideoFrame dummy; - return dummy; + // Copy data + if (final.format == FORMAT_YV12) { + memcpy(final.data[0],frame->data[0],final.w * final.h); + memcpy(final.data[1],frame->data[1],final.w * final.h / 4); + memcpy(final.data[2],frame->data[2],final.w * final.h / 4); + } + else memcpy(final.data[0],frame->data[0],size); + } + + // No frame available + else final = AegiVideoFrame(GetWidth(),GetHeight()); + + // Set current frame + validFrame = true; + curFrame = final; + frameNumber = n; + + // Return + return final; } diff --git a/aegisub/video_provider_lavc.h b/aegisub/video_provider_lavc.h index 727adb9a3..80f019e01 100644 --- a/aegisub/video_provider_lavc.h +++ b/aegisub/video_provider_lavc.h @@ -72,7 +72,7 @@ private: __int64 lastDecodeTime; int frameNumber; int length; - wxBitmap curFrame; + AegiVideoFrame curFrame; bool validFrame; uint8_t *buffer1;