Some highly failed attempt to fix mkv support with lavc, and updated manual to include information on how to use FexTracker

Originally committed to SVN as r189.
This commit is contained in:
Rodrigo Braz Monteiro 2006-03-01 03:17:31 +00:00
parent 9da55729c6
commit e7ec7ec68a
8 changed files with 79 additions and 31 deletions

View file

@ -128,7 +128,6 @@ void MatroskaWrapper::Parse() {
keyFrames.Clear();
bytePos.Clear();
timecodes.clear();
std::list<MkvFrame> frames;
// Get info
int tracks = mkv_GetNumTracks(file);
@ -184,6 +183,11 @@ void MatroskaWrapper::Parse() {
}
}
// Copy raw
for (std::list<MkvFrame>::iterator cur=frames.begin();cur!=frames.end();cur++) {
rawFrames.push_back(*cur);
}
// Process timecodes and keyframes
frames.sort();
MkvFrame curFrame(false,0,0);

View file

@ -42,6 +42,7 @@
#include <wx/wxprec.h>
#include <stdio.h>
#include <vector>
#include <list>
#include "MatroskaParser.h"
#include "vfr.h"
@ -78,8 +79,6 @@ bool operator < (MkvFrame &t1, MkvFrame &t2);
// Matroska wrapper class
class MatroskaWrapper {
private:
MatroskaFile *file;
MkvStdIO *input;
wxArrayInt keyFrames;
std::vector<double> timecodes;
wxArrayInt bytePos;
@ -87,6 +86,11 @@ private:
void Parse();
public:
MkvStdIO *input;
MatroskaFile *file;
std::list<MkvFrame> frames;
std::vector<MkvFrame> rawFrames;
MatroskaWrapper();
~MatroskaWrapper();

View file

@ -36,6 +36,10 @@
////////////
// Includes
#include <algorithm>
#include <wx/clipbrd.h>
#include <wx/tokenzr.h>
#include <wx/filename.h>
#include "subs_grid.h"
#include "ass_file.h"
#include "ass_dialogue.h"
@ -46,10 +50,7 @@
#include "options.h"
#include "frame_main.h"
#include "hotkeys.h"
#include <algorithm>
#include <wx/clipbrd.h>
#include <wx/tokenzr.h>
#include <wx/filename.h>
#include "utils.h"
///////////////
@ -812,6 +813,9 @@ void SubtitlesGrid::DeleteLines(wxArrayInt target) {
AdjustScrollbar();
ass->FlagAsModified();
CommitChanges();
// Update editbox
editBox->SetToLine(MID(0,editBox->linen,GetRows()-1));
}

View file

@ -162,6 +162,7 @@ void SRTSubtitleFormat::WriteFile(wxString _filename,wxString encoding) {
}
else throw _T("Unexpected line type");
}
ClearCopy();
}

View file

@ -37,6 +37,11 @@
#pragma once
//////////////
// Prototypes
class SubtitleRasterizer;
////////////////////////////
// Video Provider interface
class VideoProvider {
@ -61,5 +66,7 @@ public:
virtual int GetSourceWidth()=0; // Returns the original source width in pixels
virtual int GetSourceHeight()=0; // Returns the original source height in pixels
SubtitleRasterizer *subsRaster;
static VideoProvider *GetProvider(wxString video,wxString subtitles);
};

View file

@ -38,6 +38,7 @@
// Headers
#ifdef USE_LAVC
#include <wx/wxprec.h>
#include <algorithm>
#include "video_provider_lavc.h"
#include "utils.h"
#include "vfr.h"
@ -125,15 +126,15 @@ void LAVCVideoProvider::LoadVideo(wxString filename) {
if (result < 0) throw _T("Failed to open video decoder");
// Check length
isVFR = false;
isMkv = false;
length = stream->duration;
if (length <= 0) {
if (strcmp(formatContext->iformat->name,"matroska") == 0) {
throw _T("FFmpeg fails at seeking Matroska. If you have any idea on how to fix it, Aegisub is open source.");
MatroskaWrapper::wrapper.Open(filename);
length = MatroskaWrapper::wrapper.GetFrameCount();
bytePos = MatroskaWrapper::wrapper.GetBytePositions();
isVFR = true;
//throw _T("FFmpeg fails at seeking Matroska. If you have any idea on how to fix it, Aegisub is open source.");
mkv.Open(filename);
length = mkv.GetFrameCount();
bytePos = mkv.GetBytePositions();
isMkv = true;
}
if (length <= 0) throw _T("Returned invalid stream length");
}
@ -160,6 +161,9 @@ void LAVCVideoProvider::LoadVideo(wxString filename) {
///////////////
// Close video
void LAVCVideoProvider::Close() {
// Close mkv
if (isMkv) mkv.Close();
// Clean buffers
if (buffer1) delete buffer1;
if (buffer2) delete buffer2;
@ -305,39 +309,60 @@ wxBitmap LAVCVideoProvider::GetFrame(int n) {
else {
// Prepare seek
__int64 seekTo;
int result;
int result = 0;
// Get time to seek to
if (isVFR) {
if (isMkv) {
//__int64 base = AV_TIME_BASE;
//__int64 time = VFR_Output.GetTimeAtFrame(n,true) * base / 1000000;
//seekTo = av_rescale(time,stream->time_base.den,AV_TIME_BASE * __int64(stream->time_base.num));
//seekTo = __int64(n) * 1000 * stream->r_frame_rate.den / stream->r_frame_rate.num;
seekTo = bytePos[n];
//seekTo = bytePos[n];
result = av_seek_frame(formatContext,vidStream,seekTo,AVSEEK_FLAG_BACKWARD | AVSEEK_FLAG_BYTE);
//result = av_seek_frame(formatContext,vidStream,seekTo,AVSEEK_FLAG_BACKWARD | AVSEEK_FLAG_BYTE);
// Prepare mkv seek
ulonglong startTime, endTime, filePos;
unsigned int rt, frameSize, frameFlags;
ulonglong targetTime = __int64(VFR_Output.GetTimeAtFrame(n,true,true))*1000000;
//ulonglong targetTime = __int64(n) * 1000 * stream->r_frame_rate.den / stream->r_frame_rate.num;
//ulonglong targetTime = mkv.rawFrames[n].time * 1000000;
mkv_Seek(mkv.file,targetTime,MKVF_SEEK_TO_PREV_KEYFRAME);
// Seek
if (mkv_ReadFrame(mkv.file,0,&rt,&startTime,&endTime,&filePos,&frameSize,&frameFlags) == 0) {
result = av_seek_frame(formatContext,vidStream,filePos,AVSEEK_FLAG_BYTE | AVSEEK_FLAG_BACKWARD);
int curpos = 0;
for (int i=0;i<mkv.rawFrames.size();i++) {
if (mkv.rawFrames[i].time == startTime / 1000000.0) curpos = i;
}
int seek = n - curpos;
for (int i=0;i<seek;i++) {
GetNextFrame();
}
}
}
// Constant frame rate
else {
seekTo = n;
result = av_seek_frame(formatContext,vidStream,seekTo,AVSEEK_FLAG_BACKWARD);
}
// Seek to keyframe
if (result == 0) {
avcodec_flush_buffers(codecContext);
// Seek to keyframe
if (result == 0) {
avcodec_flush_buffers(codecContext);
// Seek until final frame
bool ok = true;
do {
ok = GetNextFrame();
} while (lastDecodeTime <= n && ok);
}
// Seek until final frame
bool ok = true;
do {
ok = GetNextFrame();
} while (lastDecodeTime <= n && ok);
}
// Failed seeking
else {
GetNextFrame();
// Failed seeking
else {
GetNextFrame();
}
}
}

View file

@ -52,12 +52,15 @@
#include <ffmpeg/avcodec.h>
#include <ffmpeg/avformat.h>
#include "video_provider.h"
#include "mkv_wrap.h"
///////////////////////
// LibAVCodec provider
class LAVCVideoProvider : public VideoProvider {
private:
MatroskaWrapper mkv;
AVFormatContext *formatContext;
AVCodecContext *codecContext;
AVStream *stream;
@ -72,7 +75,7 @@ private:
wxArrayInt bytePos;
bool isVFR;
bool isMkv;
__int64 lastDecodeTime;
int frameNumber;
int length;

Binary file not shown.