From 00e7b923eaf6cc842149a1a2e23cd88c5e73074d Mon Sep 17 00:00:00 2001 From: Rodrigo Braz Monteiro Date: Fri, 24 Feb 2006 03:54:40 +0000 Subject: [PATCH] Some basic LAVC code implemented Originally committed to SVN as r142. --- core/video_provider_lavc.cpp | 165 +++++++++++++++++++++++++---------- core/video_provider_lavc.h | 13 +++ 2 files changed, 133 insertions(+), 45 deletions(-) diff --git a/core/video_provider_lavc.cpp b/core/video_provider_lavc.cpp index be4cc7dca..4880af2c2 100644 --- a/core/video_provider_lavc.cpp +++ b/core/video_provider_lavc.cpp @@ -37,116 +37,191 @@ /////////// // Headers #ifdef USE_LAVC -#define EMULATE_INTTYPES #include -#include -#include #include "video_provider_lavc.h" /////////////// // Constructor LAVCVideoProvider::LAVCVideoProvider(wxString filename, wxString subfilename, double zoom) { + // Init variables + codecContext = NULL; + formatContext = NULL; + codec = NULL; + stream = NULL; + vidStream = -1; + // Register types static bool avRegistered = false; if (!avRegistered) { av_register_all(); avRegistered = true; } + + // Load + LoadVideo(filename); } ////////////// // Destructor LAVCVideoProvider::~LAVCVideoProvider() { + Close(); } -// -// +////////////// +// Load video +void LAVCVideoProvider::LoadVideo(wxString filename) { + // Close first + Close(); + + // Load + try { + // Open file + int result = 0; + result = av_open_input_file(&formatContext,filename.mb_str(wxConvLocal),NULL,0,NULL); + if (result != 0) throw _T("Failed opening file."); + + // Get stream info + result = av_find_stream_info(formatContext); + if (result < 0) throw _T("Unable to read stream info"); + + // Find video stream + vidStream = -1; + codecContext = NULL; + for (int i=0;inb_streams;i++) { + codecContext = formatContext->streams[i]->codec; + if (codecContext->codec_type == CODEC_TYPE_VIDEO) { + stream = formatContext->streams[i]; + vidStream = i; + break; + } + } + if (vidStream == -1) throw _T("Could not find a video stream"); + + // Check length + if (stream->duration <= 0) throw _T("Returned invalid stream length"); + + // Find codec + codec = avcodec_find_decoder(codecContext->codec_id); + if (!codec) throw _T("Could not find suitable video decoder"); + + // Enable truncation + if (codec->capabilities & CODEC_CAP_TRUNCATED) codecContext->flags |= CODEC_FLAG_TRUNCATED; + + // Open codec + result = avcodec_open(codecContext,codec); + if (result < 0) throw _T("Failed to open video decoder"); + } + + // Catch errors + catch (...) { + Close(); + throw; + } +} + + +/////////////// +// Close video +void LAVCVideoProvider::Close() { + // Close codec context + if (codec) avcodec_close(codecContext); + codecContext = NULL; + codec = NULL; + + // Close format context + if (formatContext) av_close_input_file(formatContext); + formatContext = NULL; +} + + +//////////////// +// Refresh subs void LAVCVideoProvider::RefreshSubtitles() { } -// -// +///////////// +// Get frame wxBitmap LAVCVideoProvider::GetFrame(int n) { - wxBitmap frame; + wxBitmap frame(GetWidth(),GetHeight()); return frame; } -// -// +////////////////////// +// Get frame as float void LAVCVideoProvider::GetFloatFrame(float* Buffer, int n) { } -// -// +//////////////// +// Get position int LAVCVideoProvider::GetPosition() { return 0; } -// -// +//////////////////////// +// Get number of frames int LAVCVideoProvider::GetFrameCount() { - return 0; + return stream->duration; } -// -// +////////////////// +// Get frame rate double LAVCVideoProvider::GetFPS() { - return 1; + return double(stream->r_frame_rate.num) / double(stream->r_frame_rate.den); } -// -// +//////////////////// +// Set aspect ratio void LAVCVideoProvider::SetDAR(double dar) { } -// -// +//////////// +// Set zoom void LAVCVideoProvider::SetZoom(double zoom) { } -// -// -int LAVCVideoProvider::GetWidth() { - return 640; -} - - -// -// -int LAVCVideoProvider::GetHeight() { - return 480; -} - - -// -// +//////////// +// Get zoom double LAVCVideoProvider::GetZoom() { return 1; } -// -// -int LAVCVideoProvider::GetSourceWidth() { - return 640; +///////////// +// Get width +int LAVCVideoProvider::GetWidth() { + return codecContext->coded_width; } -// -// +////////////// +// Get height +int LAVCVideoProvider::GetHeight() { + return codecContext->coded_height; +} + + +////////////////////// +// Get original width +int LAVCVideoProvider::GetSourceWidth() { + return codecContext->coded_width; +} + + +/////////////////////// +// Get original height int LAVCVideoProvider::GetSourceHeight() { - return 480; + return codecContext->coded_height; } diff --git a/core/video_provider_lavc.h b/core/video_provider_lavc.h index 6f6ef04b6..ea9fc1015 100644 --- a/core/video_provider_lavc.h +++ b/core/video_provider_lavc.h @@ -39,12 +39,25 @@ /////////// // Headers #ifdef USE_LAVC +#define EMULATE_INTTYPES +#include +#include #include "video_provider.h" /////////////////////// // LibAVCodec provider class LAVCVideoProvider : public VideoProvider { +private: + AVFormatContext *formatContext; + AVCodecContext *codecContext; + AVStream *stream; + AVCodec *codec; + int vidStream; + + void LoadVideo(wxString filename); + void Close(); + public: LAVCVideoProvider(wxString filename, wxString subfilename, double zoom); ~LAVCVideoProvider();