mirror of https://github.com/odrling/Aegisub
We're getting there...
Originally committed to SVN as r144.
This commit is contained in:
parent
40341df934
commit
ddc7c8b323
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue