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(); keyFrames.Clear();
bytePos.Clear(); bytePos.Clear();
timecodes.clear(); timecodes.clear();
std::list<MkvFrame> frames;
// Get info // Get info
int tracks = mkv_GetNumTracks(file); 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 // Process timecodes and keyframes
frames.sort(); frames.sort();
MkvFrame curFrame(false,0,0); MkvFrame curFrame(false,0,0);

View File

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

View File

@ -36,6 +36,10 @@
//////////// ////////////
// Includes // Includes
#include <algorithm>
#include <wx/clipbrd.h>
#include <wx/tokenzr.h>
#include <wx/filename.h>
#include "subs_grid.h" #include "subs_grid.h"
#include "ass_file.h" #include "ass_file.h"
#include "ass_dialogue.h" #include "ass_dialogue.h"
@ -46,10 +50,7 @@
#include "options.h" #include "options.h"
#include "frame_main.h" #include "frame_main.h"
#include "hotkeys.h" #include "hotkeys.h"
#include <algorithm> #include "utils.h"
#include <wx/clipbrd.h>
#include <wx/tokenzr.h>
#include <wx/filename.h>
/////////////// ///////////////
@ -812,6 +813,9 @@ void SubtitlesGrid::DeleteLines(wxArrayInt target) {
AdjustScrollbar(); AdjustScrollbar();
ass->FlagAsModified(); ass->FlagAsModified();
CommitChanges(); 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"); else throw _T("Unexpected line type");
} }
ClearCopy();
} }

View File

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

View File

@ -38,6 +38,7 @@
// Headers // Headers
#ifdef USE_LAVC #ifdef USE_LAVC
#include <wx/wxprec.h> #include <wx/wxprec.h>
#include <algorithm>
#include "video_provider_lavc.h" #include "video_provider_lavc.h"
#include "utils.h" #include "utils.h"
#include "vfr.h" #include "vfr.h"
@ -125,15 +126,15 @@ void LAVCVideoProvider::LoadVideo(wxString filename) {
if (result < 0) throw _T("Failed to open video decoder"); if (result < 0) throw _T("Failed to open video decoder");
// Check length // Check length
isVFR = false; isMkv = false;
length = stream->duration; length = stream->duration;
if (length <= 0) { if (length <= 0) {
if (strcmp(formatContext->iformat->name,"matroska") == 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."); //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); mkv.Open(filename);
length = MatroskaWrapper::wrapper.GetFrameCount(); length = mkv.GetFrameCount();
bytePos = MatroskaWrapper::wrapper.GetBytePositions(); bytePos = mkv.GetBytePositions();
isVFR = true; isMkv = true;
} }
if (length <= 0) throw _T("Returned invalid stream length"); if (length <= 0) throw _T("Returned invalid stream length");
} }
@ -160,6 +161,9 @@ void LAVCVideoProvider::LoadVideo(wxString filename) {
/////////////// ///////////////
// Close video // Close video
void LAVCVideoProvider::Close() { void LAVCVideoProvider::Close() {
// Close mkv
if (isMkv) mkv.Close();
// Clean buffers // Clean buffers
if (buffer1) delete buffer1; if (buffer1) delete buffer1;
if (buffer2) delete buffer2; if (buffer2) delete buffer2;
@ -305,39 +309,60 @@ wxBitmap LAVCVideoProvider::GetFrame(int n) {
else { else {
// Prepare seek // Prepare seek
__int64 seekTo; __int64 seekTo;
int result; int result = 0;
// Get time to seek to // Get time to seek to
if (isVFR) { if (isMkv) {
//__int64 base = AV_TIME_BASE; //__int64 base = AV_TIME_BASE;
//__int64 time = VFR_Output.GetTimeAtFrame(n,true) * base / 1000000; //__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 = 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 = __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 // Constant frame rate
else { else {
seekTo = n; seekTo = n;
result = av_seek_frame(formatContext,vidStream,seekTo,AVSEEK_FLAG_BACKWARD); result = av_seek_frame(formatContext,vidStream,seekTo,AVSEEK_FLAG_BACKWARD);
}
// Seek to keyframe // Seek to keyframe
if (result == 0) { if (result == 0) {
avcodec_flush_buffers(codecContext); avcodec_flush_buffers(codecContext);
// Seek until final frame // Seek until final frame
bool ok = true; bool ok = true;
do { do {
ok = GetNextFrame(); ok = GetNextFrame();
} while (lastDecodeTime <= n && ok); } while (lastDecodeTime <= n && ok);
} }
// Failed seeking // Failed seeking
else { else {
GetNextFrame(); GetNextFrame();
}
} }
} }

View File

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

Binary file not shown.