We're getting there...

Originally committed to SVN as r144.
This commit is contained in:
Rodrigo Braz Monteiro 2006-02-24 05:58:45 +00:00
parent 40341df934
commit ddc7c8b323
2 changed files with 44 additions and 61 deletions

View File

@ -39,6 +39,8 @@
#ifdef USE_LAVC #ifdef USE_LAVC
#include <wx/wxprec.h> #include <wx/wxprec.h>
#include "video_provider_lavc.h" #include "video_provider_lavc.h"
#include "utils.h"
#include "vfr.h"
/////////////// ///////////////
@ -111,7 +113,7 @@ void LAVCVideoProvider::LoadVideo(wxString filename) {
if (!codec) throw _T("Could not find suitable video decoder"); if (!codec) throw _T("Could not find suitable video decoder");
// Enable truncation // Enable truncation
if (codec->capabilities & CODEC_CAP_TRUNCATED) codecContext->flags |= CODEC_FLAG_TRUNCATED; //if (codec->capabilities & CODEC_CAP_TRUNCATED) codecContext->flags |= CODEC_FLAG_TRUNCATED;
// Open codec // Open codec
result = avcodec_open(codecContext,codec); result = avcodec_open(codecContext,codec);
@ -119,6 +121,9 @@ void LAVCVideoProvider::LoadVideo(wxString filename) {
// Allocate frame // Allocate frame
frame = avcodec_alloc_frame(); frame = avcodec_alloc_frame();
// Set frame
frameNumber = -1;
} }
// Catch errors // Catch errors
@ -155,64 +160,24 @@ void LAVCVideoProvider::Close() {
////////////////// //////////////////
// Get next frame // Get next frame
void LAVCVideoProvider::GetNextFrame() { void LAVCVideoProvider::GetNextFrame() {
static AVPacket packet; // Read packet
static bool firstTime = true; AVPacket packet;
static int bytesRemaining = 0; while (av_read_frame(formatContext, &packet)>=0) {
static uint8_t *rawdata; // Check if packet is part of video stream
int decoded; if(packet.stream_index == vidStream) {
int frameFinished; // Decode frame
int frameFinished;
avcodec_decode_video(codecContext, frame, &frameFinished, packet.data, packet.size);
// First call // Success?
if (firstTime) { if(frameFinished) {
firstTime = false; // Free packet
packet.data = NULL; av_free_packet(&packet);
} return;
// Start processing packets
bool run = true;
while (run) {
// Current packet has more bytes
while (bytesRemaining > 0) {
// Decode
decoded = avcodec_decode_video(codecContext,frame,&frameFinished,rawdata,bytesRemaining);
// Error?
if (decoded < 0) throw _T("Error reading frame");
// Update counts
bytesRemaining -= decoded;
rawdata += decoded;
// Finished?
if (frameFinished) return;
}
// Get a packet
do {
// Free packet
if (packet.data != NULL) av_free_packet(&packet);
// Get new
int result = av_read_packet(formatContext,&packet);
if (result < 0) {
run = false;
break;
} }
} while (packet.stream_index != vidStream);
// Get packet data
if (run) {
bytesRemaining = packet.size;
rawdata = packet.data;
} }
} }
av_free_packet(&packet);
// End of last pack
decoded = avcodec_decode_video(codecContext,frame,&frameFinished,rawdata,bytesRemaining);
if (packet.data != NULL) av_free_packet(&packet);
// Frame finished?
if (!frameFinished) throw _T("Unable to finish decoding frame");
} }
@ -254,14 +219,29 @@ void LAVCVideoProvider::RefreshSubtitles() {
///////////// /////////////
// Get frame // Get frame
wxBitmap LAVCVideoProvider::GetFrame(int n) { wxBitmap LAVCVideoProvider::GetFrame(int n) {
// Return stored frame
n = MID(0,n,GetFrameCount()-1);
if (n == frameNumber) return curFrame;
// Seek if needed
if (n != frameNumber+1) {
av_seek_frame(formatContext,vidStream,n,0);
}
// Get frame // Get frame
GetNextFrame(); GetNextFrame();
// Bitmap // Bitmap
wxBitmap bmp = AVFrameToWX(frame); wxBitmap bmp;
if (frame) bmp = AVFrameToWX(frame);
else bmp = wxBitmap(GetWidth(),GetHeight());
// Set current frame
curFrame = bmp;
frameNumber = n;
// Return // Return
return bmp; return curFrame;
} }
@ -274,7 +254,7 @@ void LAVCVideoProvider::GetFloatFrame(float* Buffer, int n) {
//////////////// ////////////////
// Get position // Get position
int LAVCVideoProvider::GetPosition() { int LAVCVideoProvider::GetPosition() {
return 0; return frameNumber;
} }

View File

@ -40,8 +40,8 @@
// Headers // Headers
#ifdef USE_LAVC #ifdef USE_LAVC
#define EMULATE_INTTYPES #define EMULATE_INTTYPES
#include <lavc/avcodec.h> #include <ffmpeg/avcodec.h>
#include <lavc/avformat.h> #include <ffmpeg/avformat.h>
#include "video_provider.h" #include "video_provider.h"
@ -56,6 +56,9 @@ private:
AVFrame *frame; AVFrame *frame;
int vidStream; int vidStream;
int frameNumber;
wxBitmap curFrame;
uint8_t *buffer; uint8_t *buffer;
int bufferSize; int bufferSize;