Merged opengl branch from 806 to 859

Originally committed to SVN as r860.
This commit is contained in:
Rodrigo Braz Monteiro 2007-01-21 06:30:19 +00:00
parent 3c7d5fe033
commit 98ce168b31
58 changed files with 4356 additions and 1870 deletions

569
aegisub/VideoSink.cpp Normal file
View file

@ -0,0 +1,569 @@
/*
* Copyright (c) 2004-2006 Mike Matsnev. All Rights Reserved.
*
* $Id: VideoSink.cpp,v 1.8 2007/01/17 23:40:51 mike Exp $
*
*/
#include "setup.h"
#if USE_DIRECTSHOW == 1
#include <windows.h>
#ifdef __WXDEBUG__
#undef __WXDEBUG__
#endif
typedef TCHAR* PTCHAR;
#include <streams.h>
#include <dvdmedia.h>
#include "VideoSink.h"
#include "initguid.h"
class CVideoSink;
// CLSID for videosink: {F13D3732-96BD-4108-AFEB-E85F68FF64DC}
//DEFINE_GUID(CLSID_AegiVideoSink, 0xf13d3732, 0x96bd, 0x4108, 0xaf, 0xeb, 0xe8, 0x5f, 0x68, 0xff, 0x64, 0xdc);
// {E9C80780-4C07-4b36-87D4-5241CD0C6FE2}
DEFINE_GUID(CLSID_AegiVideoSink, 0xe9c80780, 0x4c07, 0x4b36, 0x87, 0xd4, 0x52, 0x41, 0xcd, 0xc, 0x6f, 0xe2);
static int GetBPP(const BITMAPINFOHEADER& h) {
switch (h.biCompression) {
case MAKEFOURCC('Y','U','Y','2'): return 16;
case MAKEFOURCC('Y','V','1','2'): return 12;
case 0: return h.biBitCount;
}
return 0;
}
[uuid("2EE04A02-4AF5-43f8-B05B-5DEB66473419")]
interface IVSAllocator : public IUnknown {
STDMETHOD(SetNextMT)(const AM_MEDIA_TYPE *pMT) = 0;
};
class CVSAllocator : public CMemAllocator, public IVSAllocator {
CMediaType *m_nextmt;
public:
CVSAllocator(TCHAR *pName, LPUNKNOWN pUnk, HRESULT *phr) : CMemAllocator(pName, pUnk, phr), m_nextmt(NULL) { }
~CVSAllocator() {
delete m_nextmt;
}
STDMETHOD(SetNextMT)(const AM_MEDIA_TYPE *pMT) {
CMediaType *newMT = new CMediaType(*pMT);
newMT = (CMediaType *)InterlockedExchangePointer((void **)&m_nextmt, newMT);
if (newMT != NULL)
delete pMT;
return S_OK;
}
STDMETHOD(GetBuffer)(IMediaSample **ppS, REFERENCE_TIME *pStart, REFERENCE_TIME *pStop, DWORD dwFlags) {
CMediaType *pMT = (CMediaType *)InterlockedExchangePointer((void **)&m_nextmt, NULL);
if (pMT != NULL) {
BITMAPINFOHEADER *bmh = NULL;
if (pMT->formattype == FORMAT_VideoInfo)
bmh = &((VIDEOINFOHEADER *)pMT->pbFormat)->bmiHeader;
else if (pMT->formattype == FORMAT_VideoInfo2)
bmh = &((VIDEOINFOHEADER2 *)pMT->pbFormat)->bmiHeader;
if (bmh != NULL) {
ALLOCATOR_PROPERTIES ap, act;
Decommit();
GetProperties(&ap);
long newsize = (bmh->biWidth * abs(bmh->biHeight) * GetBPP(*bmh)) >> 3;
if (ap.cbBuffer < newsize)
ap.cbBuffer = newsize;
SetProperties(&ap, &act);
Commit();
}
}
HRESULT hr = CMemAllocator::GetBuffer(ppS, pStart, pStop, dwFlags);
if (SUCCEEDED(hr) && pMT != NULL)
(*ppS)->SetMediaType(pMT);
if (pMT != NULL)
delete pMT;
return hr;
}
DECLARE_IUNKNOWN;
STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void ** ppv) {
if (riid == __uuidof(IVSAllocator))
return GetInterface((IVSAllocator *)this, ppv);
return CMemAllocator::NonDelegatingQueryInterface(riid, ppv);
}
};
class CVideoSinkPin : public CRenderedInputPin {
bool m_changedmt;
unsigned m_types;
CVideoSink *m_sink;
HRESULT CheckMediaType(const CMediaType *pMT) {
if (pMT->majortype != MEDIATYPE_Video ||
(pMT->formattype != FORMAT_VideoInfo && pMT->formattype != FORMAT_VideoInfo2))
return VFW_E_TYPE_NOT_ACCEPTED;
if (pMT->subtype == MEDIASUBTYPE_RGB24 && m_types & IVS_RGB24)
return S_OK;
if (pMT->subtype == MEDIASUBTYPE_RGB32 && m_types & IVS_RGB32)
return S_OK;
if (pMT->subtype == MEDIASUBTYPE_YUY2 && m_types & IVS_YUY2)
return S_OK;
if (pMT->subtype == MEDIASUBTYPE_YV12 && m_types & IVS_YV12)
return S_OK;
return VFW_E_TYPE_NOT_ACCEPTED;
}
STDMETHOD(Receive)(IMediaSample *pS);
STDMETHOD(EndOfStream)();
STDMETHOD(BeginFlush)();
public:
CVideoSinkPin(CVideoSink *sink, HRESULT *phr);
STDMETHOD(GetAllocator)(IMemAllocator **ppAllocator) {
CAutoLock cObjectLock(m_pLock);
if (m_pAllocator == NULL) {
HRESULT hr = S_OK;
m_pAllocator = new CVSAllocator(NAME("CVSAllocator"), NULL, &hr);
if (FAILED(hr)) {
delete m_pAllocator;
m_pAllocator = NULL;
return hr;
}
m_pAllocator->AddRef();
}
ASSERT(m_pAllocator != NULL);
*ppAllocator = m_pAllocator;
m_pAllocator->AddRef();
return NOERROR;
}
STDMETHOD(NotifyAllocator)(IMemAllocator *pAlloc, BOOL bReadOnly) {
CAutoLock cObjectLock(m_pLock);
CComQIPtr<IVSAllocator> pVSA(pAlloc);
if (!pVSA)
return E_NOINTERFACE;
if (m_changedmt) {
m_changedmt = false;
pVSA->SetNextMT(&m_mt);
}
return CRenderedInputPin::NotifyAllocator(pAlloc, bReadOnly);
}
HRESULT SetMediaType(const CMediaType *pMT) {
HRESULT hr = CRenderedInputPin::SetMediaType(pMT);
if (FAILED(hr))
return hr;
unsigned type, width, height, bpp, arx, ary;
int stride;
if (FAILED(hr = GetFrameFormat(&type, &width, &height, &stride, &bpp, &arx, &ary, NULL)))
return hr;
if ((stride & 15) != 0) { // extend
CMediaType newMT(m_mt);
if (newMT.formattype == FORMAT_VideoInfo) {
VIDEOINFOHEADER *vh = (VIDEOINFOHEADER *)newMT.pbFormat;
vh->bmiHeader.biWidth = ((abs(stride) + 15) & ~15) / bpp;
vh->rcTarget.left = vh->rcTarget.top = 0;
vh->rcTarget.right = width;
vh->rcTarget.bottom = height;
vh->rcSource = vh->rcTarget;
} else if (newMT.formattype == FORMAT_VideoInfo2) {
VIDEOINFOHEADER2 *vh = (VIDEOINFOHEADER2 *)newMT.pbFormat;
vh->bmiHeader.biWidth = ((abs(stride) + 15) & ~15) / bpp;
vh->rcTarget.left = vh->rcTarget.top = 0;
vh->rcTarget.right = width;
vh->rcTarget.bottom = height;
vh->rcSource = vh->rcTarget;
} else
return E_FAIL;
hr = m_Connected->QueryAccept(&newMT);
if (SUCCEEDED(hr)) {
hr = CRenderedInputPin::SetMediaType(&newMT);
if (FAILED(hr))
return hr;
CComQIPtr<IVSAllocator> pVSA(m_pAllocator);
if (pVSA)
pVSA->SetNextMT(&newMT);
else
m_changedmt = true;
}
}
return S_OK;
}
BOOL AtEOF() { return m_bAtEndOfStream; }
REFERENCE_TIME SegStartTime() { return m_tStart; }
unsigned GetTypes() { return m_types; }
void SetTypes(unsigned t) { m_types = t; }
HRESULT GetFrameFormat(unsigned *type, unsigned *width, unsigned *height, int *stride,
unsigned *pbpp, unsigned *arx, unsigned *ary, long long *def_duration)
{
if (!IsConnected())
return VFW_E_NOT_CONNECTED;
unsigned bpp;
if (m_mt.subtype == MEDIASUBTYPE_RGB24)
*type = IVS_RGB24, bpp = 3;
else if (m_mt.subtype == MEDIASUBTYPE_RGB32)
*type = IVS_RGB32, bpp = 4;
else if (m_mt.subtype == MEDIASUBTYPE_YUY2)
*type = IVS_YUY2, bpp = 2;
else if (m_mt.subtype == MEDIASUBTYPE_YV12)
*type = IVS_YV12, bpp = 1;
else
return VFW_E_INVALID_MEDIA_TYPE;
if (pbpp)
*pbpp = bpp;
BITMAPINFOHEADER *bmh;
RECT rct;
if (m_mt.formattype == FORMAT_VideoInfo && m_mt.FormatLength() >= sizeof(VIDEOINFOHEADER)) {
VIDEOINFOHEADER *vh = (VIDEOINFOHEADER *)m_mt.Format();
bmh = &vh->bmiHeader;
rct = vh->rcTarget;
if (arx)
*arx = 1;
if (*ary)
*ary = 1;
if (def_duration)
*def_duration = vh->AvgTimePerFrame;
} else if (m_mt.formattype == FORMAT_VideoInfo2 && m_mt.FormatLength() >= sizeof(VIDEOINFOHEADER2)) {
VIDEOINFOHEADER2 *vh = (VIDEOINFOHEADER2 *)m_mt.Format();
bmh = &vh->bmiHeader;
rct = vh->rcTarget;
if (arx)
*arx = vh->dwPictAspectRatioX;
if (ary)
*ary = vh->dwPictAspectRatioY;
if (def_duration)
*def_duration = vh->AvgTimePerFrame;
} else
return VFW_E_INVALID_MEDIA_TYPE;
if (stride)
*stride = (bmh->biHeight > 0 && bmh->biCompression == 0 ? -1 : 1) * (int)bmh->biWidth * (int)bpp;
if (rct.right != 0)
*width = rct.right - rct.left;
else
*width = bmh->biWidth;
if (rct.bottom != 0)
*height = rct.bottom - rct.top;
else
*height = abs(bmh->biHeight);
return S_OK;
}
DECLARE_IUNKNOWN;
};
class CVideoSink :
public CBaseFilter,
public IVideoSink,
public IVideoSink2,
public IAMFilterMiscFlags
{
CVideoSinkPin *m_pin;
CRendererPosPassThru *m_rpp;
CCritSec m_lock;
int GetPinCount() { return 1; }
CBasePin *GetPin(int n) { return n == 0 ? m_pin : NULL; }
CComPtr<IMediaSample> m_sample;
HANDLE m_hEvent1, m_hEvent2, m_hNotify;
CComPtr<IVideoSinkNotify> m_notify;
public:
CVideoSink(IUnknown *pUnk, HRESULT *phr) :
CBaseFilter(_T("CVideoSink"), pUnk, &m_lock, CLSID_AegiVideoSink),
m_pin(NULL),
m_rpp(NULL)
{
m_pin = new CVideoSinkPin(this, phr);
if (FAILED(*phr))
return;
m_rpp = new CRendererPosPassThru(NAME("CVideoSink PosPassThru"), CBaseFilter::GetOwner(), phr, m_pin);
if (FAILED(*phr))
return;
m_hEvent1 = CreateEvent(NULL, FALSE, FALSE, NULL);
m_hEvent2 = CreateEvent(NULL, FALSE, FALSE, NULL);
m_hNotify = NULL;
}
~CVideoSink() {
m_sample = NULL;
delete m_rpp;
delete m_pin;
CloseHandle(m_hEvent1);
CloseHandle(m_hEvent2);
}
CCritSec *pStateLock() { return m_pLock; }
// called when lock is held
HRESULT Receive(IMediaSample *pS) {
if (pS == NULL)
m_rpp->EOS();
else
m_rpp->RegisterMediaTime(pS);
// notify callback
CComPtr<IVideoSinkNotify> notify = m_notify;
HANDLE hNotify = m_hNotify;
if (notify || hNotify) {
// save our sample
m_sample = pS;
// notify receiver
SetEvent(m_hEvent1);
}
pStateLock()->Unlock();
if (notify || hNotify) {
if (notify)
notify->FrameReady();
if (hNotify)
SetEvent(hNotify);
// wait until the thing is processed
WaitForSingleObject(m_hEvent2, INFINITE);
}
if (pS == NULL)
NotifyEvent(EC_COMPLETE, 0, (LONG_PTR)static_cast<IBaseFilter*>(this));
return S_OK;
}
HRESULT BeginFlush() {
CAutoLock lock(pStateLock());
ResetEvent(m_hEvent1);
m_sample = NULL;
SetEvent(m_hEvent2);
return S_OK;
}
STDMETHOD(Stop)() {
BeginFlush();
return CBaseFilter::Stop();
}
// IVideoSink
STDMETHOD(SetAllowedTypes)(unsigned types) {
CAutoLock lock(pStateLock());
m_pin->SetTypes(types);
return S_OK;
}
STDMETHOD(GetAllowedTypes)(unsigned *types) {
CheckPointer(types, E_POINTER);
CAutoLock lock(pStateLock());
*types = m_pin->GetTypes();
return S_OK;
}
STDMETHOD(NotifyFrame)(IVideoSinkNotify *notify) {
CAutoLock lock(pStateLock());
m_notify = notify;
return S_OK;
}
STDMETHOD(GetFrameFormat)(unsigned *type, unsigned *width, unsigned *height, unsigned *arx, unsigned *ary) {
CheckPointer(type, E_POINTER);
CheckPointer(width, E_POINTER);
CheckPointer(height, E_POINTER);
CAutoLock lock(pStateLock());
return m_pin->GetFrameFormat(type, width, height, NULL, NULL, arx, ary, NULL);
}
STDMETHOD(ReadFrame)(ReadFrameFunc f, void *arg) {
{
CAutoLock lock(pStateLock());
if (m_pin->AtEOF()) {
if (WaitForSingleObject(m_hEvent1, 0) == WAIT_OBJECT_0)
SetEvent(m_hEvent2);
return S_FALSE;
}
}
WaitForSingleObject(m_hEvent1, INFINITE);
HRESULT hr = S_OK;
{
CAutoLock lock(pStateLock());
CComPtr<IMediaSample> pS(m_sample);
m_sample = NULL;
if (!pS)
hr = S_FALSE;
else {
REFERENCE_TIME rtS, rtE;
if (SUCCEEDED(pS->GetTime(&rtS, &rtE)))
rtS += m_pin->SegStartTime();
else
rtS = -1;
if (f) {
unsigned type, srcW, srcH, arx, ary, srcBPP;
int srcS;
BYTE *srcP;
if (FAILED(m_pin->GetFrameFormat(&type, &srcW, &srcH, &srcS, &srcBPP, &arx, &ary, NULL)) ||
FAILED(pS->GetPointer(&srcP)))
hr = E_FAIL;
else {
if (srcS < 0)
srcP += abs(srcS) * (srcH - 1);
f(rtS, type, srcBPP, srcP, srcW, srcH, srcS, arx, ary, arg);
}
}
}
}
SetEvent(m_hEvent2);
return hr;
}
// IVideoSink2
STDMETHOD(NotifyFrame)(HANDLE hEvent) {
m_hNotify = hEvent;
return S_OK;
}
STDMETHOD(GetFrameFormat)(unsigned *type, unsigned *width, unsigned *height, unsigned *arx, unsigned *ary, long long *def_duration) {
CheckPointer(type, E_POINTER);
CheckPointer(width, E_POINTER);
CheckPointer(height, E_POINTER);
CAutoLock lock(pStateLock());
return m_pin->GetFrameFormat(type, width, height, NULL, NULL, arx, ary, def_duration);
}
// IAMFilterMiscFlags
STDMETHOD_(ULONG, GetMiscFlags)() { return AM_FILTER_MISC_FLAGS_IS_RENDERER; }
// COM
DECLARE_IUNKNOWN;
STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void ** ppv) {
CAutoLock lock(pStateLock());
if (riid == __uuidof(IVideoSink))
return GetInterface((IVideoSink *)this, ppv);
if (riid == __uuidof(IVideoSink2))
return GetInterface((IVideoSink2 *)this, ppv);
if (riid == __uuidof(IAMFilterMiscFlags))
return GetInterface((IAMFilterMiscFlags *)this, ppv);
if (riid == IID_IMediaSeeking || riid == IID_IMediaPosition)
return m_rpp->NonDelegatingQueryInterface(riid, ppv);
return CBaseFilter::NonDelegatingQueryInterface(riid, ppv);
}
};
CVideoSinkPin::CVideoSinkPin(CVideoSink *sink, HRESULT *phr) :
CRenderedInputPin(_T("CVideoSinkPin"), sink, sink->pStateLock(), phr, L"Input"),
m_types(IVS_RGB32),
m_sink(sink),
m_changedmt(false)
{
}
HRESULT CVideoSinkPin::Receive(IMediaSample *pS) {
m_pLock->Lock();
if (m_bFlushing) {
m_pLock->Unlock();
return S_FALSE;
}
CMediaType MT;
AM_MEDIA_TYPE *pMT;
if (SUCCEEDED(pS->GetMediaType(&pMT)) && pMT != NULL) {
MT.Set(*pMT); DeleteMediaType(pMT);
HRESULT hr = CheckMediaType(&MT);
if (FAILED(hr)) {
m_pLock->Unlock();
return hr;
}
SetMediaType(&MT);
}
if (pS->IsPreroll() == S_OK) {
m_pLock->Unlock();
return S_OK;
}
return m_sink->Receive(pS);
}
HRESULT CVideoSinkPin::EndOfStream() {
HRESULT hr1, hr2;
m_pLock->Lock();
hr1 = CRenderedInputPin::EndOfStream();
if (m_bFlushing) {
m_pLock->Unlock();
return hr1;
}
hr2 = m_sink->Receive(NULL);
if (FAILED(hr1))
return hr1;
return hr2;
}
HRESULT CVideoSinkPin::BeginFlush() {
HRESULT hr = CRenderedInputPin::BeginFlush();
m_sink->BeginFlush();
return hr;
}
//CUnknown * WINAPI CreateVideoSink(IUnknown *pUnk, HRESULT *phr) {
// CVideoSink *vs = new CVideoSink(pUnk, phr);
// if (vs == NULL)
// *phr = E_OUTOFMEMORY;
// else if (FAILED(*phr)) {
// delete vs;
// vs = NULL;
// }
// return vs;
//}
HRESULT CreateVideoSink(IBaseFilter **pVS) {
HRESULT hr = S_OK;
CVideoSink *vs = new CVideoSink(NULL,&hr);
if (vs == NULL) hr = E_OUTOFMEMORY;
else if (FAILED(hr)) {
delete vs;
vs = NULL;
}
vs->AddRef();
*pVS = vs;
return hr;
}
#endif

View file

@ -1,7 +1,7 @@
/*
* Copyright (c) 2004-2006 Mike Matsnev. All Rights Reserved.
*
* $Id: VideoSink.h,v 1.4 2006/11/12 18:00:20 mike Exp $
* $Id: VideoSink.h,v 1.5 2007/01/17 23:40:51 mike Exp $
*
*/
@ -22,7 +22,7 @@ interface IVideoSinkNotify : public IUnknown {
#define IVS_YV12 8
typedef void (*ReadFrameFunc)(long long timestamp, unsigned format, unsigned bpp,
const unsigned char *frame, unsigned width, unsigned height, unsigned stride,
const unsigned char *frame, unsigned width, unsigned height, int stride,
unsigned arx, unsigned ary,
void *arg);
@ -46,4 +46,7 @@ interface IVideoSink2 : public IUnknown {
STDMETHOD(GetFrameFormat)(unsigned *type, unsigned *width, unsigned *height, unsigned *arx, unsigned *ary, long long *def_duration) = 0;
};
HRESULT CreateVideoSink(IBaseFilter **pVS);
#endif

View file

@ -124,9 +124,9 @@ wxArrayString AssExporter::GetAllFilterNames() {
}
//////////
// Export
void AssExporter::Export(wxString filename, wxString charset, wxWindow *export_dialog) {
////////////////////////
// Transform for export
AssFile *AssExporter::ExportTransform(wxWindow *export_dialog) {
// Copy
AssFile *Subs = new AssFile(*OriginalSubs);
@ -136,20 +136,16 @@ void AssExporter::Export(wxString filename, wxString charset, wxWindow *export_d
(*cur)->ProcessSubs(Subs, export_dialog);
}
/*
// Set charset
bool withCharset = !IsDefault;
wxString charset = _T("");
if (withCharset) {
wxArrayString choices = FrameMain::GetEncodings();
charset = wxGetSingleChoice(_T("Choose charset code:"), _T("Charset"),choices,NULL,-1, -1,true,250,200);
if (charset.IsEmpty()) {
delete Subs;
return;
}
}
*/
// *FIXME* (or is it?) We assume charset argument is valid here
// Done
return Subs;
}
//////////
// Export
void AssExporter::Export(wxString filename, wxString charset, wxWindow *export_dialog) {
// Get transformation
AssFile *Subs = ExportTransform(export_dialog);
// Save
Subs->Save(filename,false,false,charset);

View file

@ -73,8 +73,9 @@ public:
void AddFilter(wxString name);
void AddAutoFilters();
void DrawSettings(wxWindow *parent,wxSizer *AddTo);
void Export(wxString file, wxString charset, wxWindow *export_dialog=NULL);
AssFile *ExportTransform(wxWindow *export_dialog=NULL);
wxSizer *GetSettingsSizer(wxString name);
void Export(wxString file, wxString charset, wxWindow *export_dialog);
AssFile *GetOriginalSubs() { return OriginalSubs; }
wxString GetDescription(wxString name);
};

View file

@ -182,7 +182,7 @@ void AssFile::Save(wxString _filename,bool setfilename,bool addToRecent,const wx
void AssFile::Export(wxString _filename) {
AssExporter exporter(this);
exporter.AddAutoFilters();
exporter.Export(_filename,_T("UTF-8"), 0);
exporter.Export(_filename,_T("UTF-8"));
}

View file

@ -53,6 +53,7 @@ AssOverrideParameter::AssOverrideParameter () {
//////////////
// Destructor
AssOverrideParameter::~AssOverrideParameter () {
DeleteValue();
}

View file

@ -120,6 +120,14 @@ AudioDisplay::~AudioDisplay() {
delete spectrumDisplaySelected;
delete peak;
delete min;
provider = NULL;
player = NULL;
origImage = NULL;
spectrumRenderer = NULL;
spectrumDisplay = NULL;
spectrumDisplaySelected = NULL;
peak = NULL;
min = NULL;
}
@ -237,8 +245,8 @@ void AudioDisplay::UpdateImage(bool weak) {
}
// Draw keyframes
if (video->KeyFramesLoaded() && draw_boundary_lines) {
wxArrayInt KeyFrames = video->GetKeyFrames();
if (VideoContext::Get()->KeyFramesLoaded() && draw_boundary_lines) {
wxArrayInt KeyFrames = VideoContext::Get()->GetKeyFrames();
int nKeys = (int)KeyFrames.Count();
dc.SetPen(wxPen(wxColour(255,0,255),1));
@ -784,12 +792,11 @@ void AudioDisplay::SetFile(wxString file, VideoProvider *vprovider) {
///////////////////
// Load from video
void AudioDisplay::SetFromVideo() {
if (video->loaded) {
wxString extension = video->videoName.Right(4);
if (VideoContext::Get()->IsLoaded()) {
wxString extension = VideoContext::Get()->videoName.Right(4);
extension.LowerCase();
if (extension != _T(".d2v"))
SetFile(video->videoName, video->provider);
if (extension != _T(".d2v")) SetFile(VideoContext::Get()->videoName, VideoContext::Get()->GetProvider());
}
}
@ -853,10 +860,10 @@ void AudioDisplay::Play(int start,int end) {
// Check provider
if (!provider) {
// Load temporary provider from video
if (video->loaded) {
if (VideoContext::Get()->IsLoaded()) {
try {
// Get provider
provider = AudioProvider::GetAudioProvider(video->videoName, this, video->provider,0);
provider = AudioProvider::GetAudioProvider(VideoContext::Get()->videoName, this, VideoContext::Get()->GetProvider(),0);
// Get player
player = AudioPlayer::GetAudioPlayer();
@ -896,7 +903,7 @@ void AudioDisplay::Stop() {
if (!player) return;
player->Stop();
if (video && video->IsPlaying) video->Stop();
if (video && VideoContext::Get()->IsPlaying()) VideoContext::Get()->Stop();
}
@ -1501,9 +1508,9 @@ int AudioDisplay::GetBoundarySnap(int ms,int rangeX,bool start) {
// Find the snap boundaries
wxArrayInt boundaries;
if (video->KeyFramesLoaded() && Options.AsBool(_T("Audio Draw Secondary Lines"))) {
if (VideoContext::Get()->KeyFramesLoaded() && Options.AsBool(_T("Audio Draw Secondary Lines"))) {
__int64 keyMS;
wxArrayInt keyFrames = video->GetKeyFrames();
wxArrayInt keyFrames = VideoContext::Get()->GetKeyFrames();
int frame;
for (unsigned int i=0;i<keyFrames.Count();i++) {
frame = keyFrames[i];

View file

@ -640,7 +640,7 @@ void BaseGrid::OnMouseEvent(wxMouseEvent &event) {
// Normal click
if ((click || dclick) && !shift && !ctrl && !alt) {
if (editBox->linen != row) editBox->SetToLine(row);
if (dclick) video->JumpToFrame(VFR_Output.GetFrameAtTime(GetDialogue(row)->Start.GetMS(),true));
if (dclick) VideoContext::Get()->JumpToFrame(VFR_Output.GetFrameAtTime(GetDialogue(row)->Start.GetMS(),true));
SelectRow(row,false);
parentFrame->UpdateToolbar();
lastRow = row;
@ -875,10 +875,10 @@ AssDialogue *BaseGrid::GetDialogue(int n) {
////////////////////////////////////
// Check if line is being displayed
bool BaseGrid::IsDisplayed(AssDialogue *line) {
if (!video->loaded) return false;
if (!VideoContext::Get()->IsLoaded()) return false;
int f1 = VFR_Output.GetFrameAtTime(line->Start.GetMS(),true);
int f2 = VFR_Output.GetFrameAtTime(line->End.GetMS(),false);
if (f1 <= video->frame_n && f2 >= video->frame_n) return true;
if (f1 <= VideoContext::Get()->GetFrameN() && f2 >= VideoContext::Get()->GetFrameN()) return true;
return false;
}
@ -944,7 +944,7 @@ void BaseGrid::OnKeyPress(wxKeyEvent &event) {
// Left/right, forward to seek bar if video is loaded
if (key == WXK_LEFT || key == WXK_RIGHT) {
if (video->loaded) {
if (VideoContext::Get()->IsLoaded()) {
video->ControlSlider->SetFocus();
video->ControlSlider->AddPendingEvent(event);
return;
@ -1036,8 +1036,8 @@ void BaseGrid::OnKeyPress(wxKeyEvent &event) {
}
// Other events, send to audio display
if (video->audio->loaded) {
video->audio->AddPendingEvent(event);
if (VideoContext::Get()->audio->loaded) {
VideoContext::Get()->audio->AddPendingEvent(event);
}
else event.Skip();
}

300
aegisub/csri/csri.h Normal file
View file

@ -0,0 +1,300 @@
/*****************************************************************************
* csri: common subtitle renderer interface
*****************************************************************************
* Copyright (C) 2007 David Lamparter
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
****************************************************************************/
/** \file csri.h - main CSRI (common subtitle renderer interface) include.
* $Id: csri.h 5 2007-01-19 17:50:13Z equinox $ */
#ifndef _CSRI_H
/** \cond */
#define _CSRI_H 20070119
/** \endcond */
#include <stddef.h> /* ptrdiff_t */
#ifdef __cplusplus
extern "C" {
#endif
#ifndef CSRIAPI
#if defined(WIN32) || defined(DOXYGEN)
/** CSRI API attributes.
* defaults to \c extern / \c extern \c __cdecl on Windows.
*/
#define CSRIAPI extern __cdecl
#else
#define CSRIAPI extern
#endif
#endif
/** \defgroup base CSRI base API. */
/*@{*/
/** pixel format specification for frames */
enum csri_pixfmt {
CSRI_F_RGBA = 0,
CSRI_F_ARGB,
CSRI_F_BGRA,
CSRI_F_ABGR,
CSRI_F_RGB_ = 0x100,
CSRI_F__RGB,
CSRI_F_BGR_, /**< Windows "RGB32" */
CSRI_F__BGR,
CSRI_F_RGB = 0x200,
CSRI_F_BGR, /**< Windows "RGB24" */
CSRI_F_AYUV = 0x1000,
CSRI_F_YUVA,
CSRI_F_YVUA,
CSRI_F_YUY2 = 0x1100,
CSRI_F_YV12A = 0x2011, /**< planar YUV 2x2 + alpha plane */
CSRI_F_YV12 = 0x2111 /**< planar YUV 2x2 */
};
#define csri_is_rgb(x) ((x) < 0x1000)
#define csri_is_yuv(x) ((x) >= 0x1000)
#define csri_is_yuv_planar(x) ((x) >= 0x2000)
#define csri_get_yuv_planar_xred(x) (0xf & (x))
#define csri_get_yuv_planar_yred(x) (0xf & ((x) >> 4))
#define csri_is_yuv_packed(x) ((x) >= 0x1000 && (x) < 0x2000)
#define csri_has_alpha(x) (((x) & 0xfff) < 0x100)
/** frame/image format specification pre-fed to the renderer */
struct csri_fmt {
/** format to be used */
enum csri_pixfmt pixfmt;
/** image width, full frame.
*
* This should specify the full size of the frame.
* Specifying the video sub-size (in case of added black
* borders) is left to an extension.
*/
unsigned width;
/** image height */
unsigned height;
};
/** single frame to be fed to the renderer. */
struct csri_frame {
/** frame format.
* It is an application bug if this differs from the one
* passed in struct #csri_fmt to csri_query_fmt()
*/
enum csri_pixfmt pixfmt;
/** the frame's data.
* Packed formats only use planes[0]; planar formats
* have the data ordered as Y, U, V[, A].
*
* Also note that the topmost line always comes first.
* The Windows biHeight strange-ity is \a NOT duplicated.
*/
unsigned char *planes[4];
/** strides for the individual planes.
* Stride means full byte offset, i.e. do \a not add
* frame width
*/
ptrdiff_t strides[4];
};
#ifndef CSRI_OWN_HANDLES
/** opaque renderer data */
typedef void csri_rend;
/** opaque instance data */
typedef void csri_inst;
#endif
#ifdef DOXYGEN
/** disable the emission of the csri_rend and csri_inst typedefs.
* define this if you are in a renderer and are typedef'ing
* csri_rend and csri_inst to your own structs.
*/
#define CSRI_OWN_HANDLES
#endif
/** renderer description */
struct csri_info {
/** an identifier for the renderer.
* - MUST match the regular expression
* \code ^[a-zA-Z]([a-zA-Z0-9_]*[a-zA-Z0-9])? \endcode
* i.e. consists only of letters, numbers and underscores;
* must start with a letter and doesnt have an underscore
* as the last character.
*/
const char *name;
/** an identifier to the exact version of the renderer.
* most likely a version number or revision identifier.
*
* The helper library does a strcmp over this field in order
* to order multiple instances of the same renderer. Use
* higher-byte-value strings for newer renderers.
*/
const char *specific;
/** a nice name to be presented to the user */
const char *longname;
/** the renderer's author */
const char *author;
/** a copyright string. Copyright (c) 2042 by Mr. Nice Guy */
const char *copyright;
};
/** data of extension-dependent type.
* The field to be used MUST be specified in the extension where it is used.
*/
union csri_vardata {
long lval;
double dval;
const char *utf8val;
void *otherval;
};
/** extension identifier.
* This follows reverse DNS syntax, i.e.:
* \code root.branch.leaf \endcode
* you can either reverse a registered domain name, e.g.
* \code com.microsoft.csri.usegdiplus \endcode
* or ask the CSRI maintainers to assign a namespace to you.
*
* currently registered namespaces are:
*
* \code
* csri.* - official extensions
* asa.* - custom extensions of the asa renderer
* \endcode
*/
typedef const char *csri_ext_id;
/** script loading parameters.
* each flag MUST have an associated extension, which can be queried
* with csri_query_ext(). If the open flag constitutes an extension on its
* sole own, csri_query_ext() can return a meaningless non-NULL value for
* it.
*
* The data field used must be specified.
*
* An extension can have multiple flags. In that case, the flags should have
* the extension name as common prefix, separated with a dot.
*
* A renderer MUST ignore unknown open flags. It MUST NOT return an error
* just because it does not support a particular flag.
*/
struct csri_openflag {
/** flag name */
csri_ext_id name;
/** flag data argument */
union csri_vardata data;
/** link to next flag */
struct csri_openflag *next;
};
/** load a script from a file.
* \param renderer the handle to the renderer
* \param filename the path to the file to be loaded. \n
* The filename should be encoded as UTF-8. Windows renderers are
* expected to convert it to UTF-16 and use the Unicode Windows API
* functions.
* \param flags a linked list of open flags. \n
* The caller manages memory allocation, i.e. static allocation is OK.
* \return the renderer instance handle, or NULL on error.
*/
CSRIAPI csri_inst *csri_open_file(csri_rend *renderer,
const char *filename, struct csri_openflag *flags);
/** load a script from memory.
* \param renderer the handle to the renderer
* \param data pointer to the first data byte. \n
* The caller manages memory allocation and should free the data after
* calling csri_open_mem(). If the renderer needs to keep the data, it
* must copy it. \n
* The renderer is not allowed to write to the data.
* \param length length, in bytes, of the data
* \param flags see csri_open_file()
* \return the render instance handle, or NULL on error.
*/
CSRIAPI csri_inst *csri_open_mem(csri_rend *renderer,
const void *data, size_t length, struct csri_openflag *flags);
/** close a renderer instance.
* \param inst the instance handle.
*/
CSRIAPI void csri_close(csri_inst *inst);
/** query / set the image format and size.
* \param inst the renderer instance handle
* \param fmt the format and image size to be used
* \return 0 if the format was successfully set,
* any other value in case of error.
*/
CSRIAPI int csri_query_fmt(csri_inst *inst, const struct csri_fmt *fmt);
/** render a single frame
* \param inst the renderer instance handle
* \param frame frame data to render to
* \param time associated timestamp of the frame
*/
CSRIAPI void csri_render(csri_inst *inst, struct csri_frame *frame,
double time);
/** query for an extension.
* \param rend the renderer handle
* \param extname the extension's identifier
* \return NULL if the extension is not supported,
* a pointer to extension-specific data otherwise
*
* The data pointed to by the return value does not neccessarily need to
* have any meaning; An extension that does not need to return data
* can return a pointer to whatever it wants, as long as that pointer is
* not NULL.
*
* In the usual case, the pointer is supposed to point to a struct with
* function pointers and other information as needed.
*/
CSRIAPI void *csri_query_ext(csri_rend *rend, csri_ext_id extname);
/** get renderer information
* \param rend the renderer handle
* \return information about the renderer, or NULL in case the renderer
* encountered an internal error.
*/
CSRIAPI struct csri_info *csri_renderer_info(csri_rend *rend);
/*@}*/
#ifdef __cplusplus
}
#endif
#endif /* _CSRI_H */

95
aegisub/csri/loader.h Normal file
View file

@ -0,0 +1,95 @@
/*****************************************************************************
* csri: common subtitle renderer interface
*****************************************************************************
* Copyright (C) 2007 David Lamparter
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
****************************************************************************/
/** \file loader.h - CSRI helper library functions.
* $Id: loader.h 3 2007-01-19 12:04:43Z equinox $ */
#ifndef _CSRI_HELPER_H
/** \cond */
#define _CSRI_HELPER_H 20070119
/** \endcond */
#if _CSRI_HELPER_H != _CSRI_H
#error CSRI helper API header doesn't match CSRI header
#endif
#ifdef __cplusplus
extern "C" {
#endif
/** \defgroup help CSRI helper/loader API.
*
* These functions locate renderers based on given parameters.
*
* <b>Renderers must implement these functions as well.</b>
*
* They are used by the library to grab renderer information
* from a shared object; and also this way a single renderer
* can be linked directly into an appliaction.
*/
/*@{*/
/** try to load a given renderer
* \param name the name of the renderer, as in csri_info.name
* \param specific the specific version of the renderer,
* as in csri_info.specific;\n
* alternatively NULL if any version of the renderer is ok.
* \return a handle to the renderer if it was successfully loaded,
* NULL otherwise.
*/
CSRIAPI csri_rend *csri_renderer_byname(const char *name,
const char *specific);
/** get the default (highest priority) renderer
* \return a handle to the default renderer, or NULL if
* no renderer is installed.
*
* Together with csri_renderer_next(), this can be used
* to enumerate all installed renderers.
*/
CSRIAPI csri_rend *csri_renderer_default();
/** get the next lower priority renderer
* \param prev the current renderer
* \return the renderer with the next lower priority than
* the one named in prev, or NULL if prev is the last
* renderer installed.
*/
CSRIAPI csri_rend *csri_renderer_next(csri_rend *prev);
/*@}*/
#ifdef __cplusplus
}
#endif
#endif /* _CSRI_HELPER_H */

View file

@ -78,6 +78,7 @@ AboutScreen::AboutScreen(wxWindow *parent)
libString += _T("asa - Copyright (c) 2004-2007, David Lamparter;\n");
#endif
libString += _T("MyThes - Copyright (c) 2003 Kevin B. Hendricks, Stratford, Ontario, Canada\n");
libString += _T("Matroska Parser and VideoSink - Copyright (c) 2004-2007 Mike Matsnev\n");
// Generate about string
wxString aboutString;
@ -88,13 +89,13 @@ AboutScreen::AboutScreen(wxWindow *parent)
aboutString += _T("Automation - Copyright (c) 2005-2007 Niels Martin Hansen (aka jfs).\n");
aboutString += _T("Motion Tracker - Copyright (c) 2006 Hajo Krabbenhoeft (aka Tentacle).\n");
aboutString += _("Programmers: ");
aboutString += _T(" ArchMageZeratuL, jfs, Myrsloik, equinox, Tentacle, Yuvi,\n Azzy, Pomyk, Motoko-chan, Dansolo.\n");
aboutString += _T(" ArchMageZeratuL, jfs, Myrsloik, equinox, Tentacle, Yuvi,\n Azzy, Pomyk, Motoko-chan, Dansolo, Haali.\n");
aboutString += _("Manual by: ");
aboutString += _T("ArchMage ZeratuL, jfs, movax, Kobi, TheFluff, Jcubed.\n");
aboutString += _("Forum, wiki and bug tracker hosting by: ");
aboutString += _T("Bot1.\n");
aboutString += _("SVN hosting by: ");
aboutString += _T("BerliOS, Mentar.\n");
aboutString += _T("equinox, BerliOS, Mentar.\n");
aboutString += translatorCredit;
aboutString += _T("\n") + libString;
aboutString += _("\nSee the help file for full credits.\n");

View file

@ -49,7 +49,7 @@ DialogJumpTo::DialogJumpTo (wxWindow *parent,VideoDisplay *_vid)
// Set initial values
ready = false;
vid = _vid;
jumpframe = vid->frame_n;
jumpframe = VideoContext::Get()->GetFrameN();
jumptime.SetMS(VFR_Output.GetTimeAtFrame(jumpframe));
// Times
@ -122,7 +122,7 @@ void DialogJumpToEvent::OnEditFrame (wxCommandEvent &event) { control->OnEditFra
void DialogJumpTo::OnKey(wxKeyEvent &event) {
int key = event.GetKeyCode();
if (key == WXK_RETURN) {
vid->JumpToFrame(jumpframe);
VideoContext::Get()->JumpToFrame(jumpframe);
EndModal(0);
return;
}
@ -133,7 +133,7 @@ void DialogJumpTo::OnKey(wxKeyEvent &event) {
////////////////////////
// On OK button pressed
void DialogJumpTo::OnClose(bool ok) {
if (ok) vid->JumpToFrame(jumpframe);
if (ok) VideoContext::Get()->JumpToFrame(jumpframe);
EndModal(0);
}

View file

@ -317,7 +317,7 @@ DialogOptions::DialogOptions(wxWindow *parent)
wxSizer *videoSizer1 = new wxStaticBoxSizer(wxVERTICAL,videoPage,_("Options"));
wxSizer *videoSizer2 = new wxStaticBoxSizer(wxVERTICAL,videoPage,_("Advanced - EXPERT USERS ONLY"));
wxFlexGridSizer *videoSizer3 = new wxFlexGridSizer(5,2,5,5);
wxFlexGridSizer *videoSizer4 = new wxFlexGridSizer(4,2,5,5);
wxFlexGridSizer *videoSizer4 = new wxFlexGridSizer(3,2,5,5);
wxControl *control;
// First sizer
@ -367,11 +367,6 @@ DialogOptions::DialogOptions(wxWindow *parent)
control = new wxComboBox(videoPage,-1,_T(""),wxDefaultPosition,wxDefaultSize,choices4,wxCB_DROPDOWN | wxCB_READONLY);
Bind(control,_T("Video provider"),1);
videoSizer4->Add(control,1,wxEXPAND);
videoSizer4->Add(new wxStaticText(videoPage,-1,_("Avisynth video resizer: ")),0,wxALIGN_CENTER_VERTICAL | wxRIGHT,10);
wxString choices5[3] = { _T("BilinearResize"), _T("BicubicResize"), _T("LanczosResize") };
control = new wxComboBox(videoPage,-1,_T(""),wxDefaultPosition,wxDefaultSize,3,choices5,wxCB_DROPDOWN);
Bind(control,_T("Video resizer"));
videoSizer4->Add(control,1,wxEXPAND);
videoSizer4->Add(new wxStaticText(videoPage,-1,_("Avisynth memory limit: ")),0,wxALIGN_CENTER_VERTICAL | wxRIGHT,10);
control = new wxTextCtrl(videoPage,-1,_T(""),wxDefaultPosition,wxDefaultSize,0,NumValidator(NULL,false));
Bind(control,_T("Avisynth memorymax"));

View file

@ -99,7 +99,7 @@ DialogProperties::DialogProperties (wxWindow *parent, VideoDisplay *_vid)
ResY = new wxTextCtrl(this,-1,_T(""),wxDefaultPosition,wxSize(50,20),0,NumValidator(&ResYValue));
wxStaticText *ResText = new wxStaticText(this,-1,_T("x"));
wxButton *FromVideo = new wxButton(this,BUTTON_FROM_VIDEO,_("From video"));
if (!vid->loaded) FromVideo->Enable(false);
if (!VideoContext::Get()->IsLoaded()) FromVideo->Enable(false);
ResSizer->Add(ResX,1,wxRIGHT,5);
ResSizer->Add(ResText,0,wxALIGN_CENTER | wxRIGHT,5);
ResSizer->Add(ResY,1,wxRIGHT,5);
@ -209,7 +209,7 @@ int DialogProperties::SetInfoIfDifferent(wxString key,wxString value) {
//////////////////////////
// Set res to match video
void DialogProperties::OnSetFromVideo(wxCommandEvent &event) {
ResX->SetValue(wxString::Format(_T("%i"),vid->provider->GetSourceWidth()));
ResY->SetValue(wxString::Format(_T("%i"),vid->provider->GetSourceHeight()));
ResX->SetValue(wxString::Format(_T("%i"),VideoContext::Get()->GetWidth()));
ResY->SetValue(wxString::Format(_T("%i"),VideoContext::Get()->GetHeight()));
event.Skip();
}

View file

@ -68,7 +68,7 @@ DialogResample::DialogResample(wxWindow *parent, SubtitlesGrid *_grid)
ResY = new wxTextCtrl(this,-1,_T(""),wxDefaultPosition,wxSize(50,20),0,NumValidator(&ResYValue));
wxStaticText *ResText = new wxStaticText(this,-1,_("x"));
wxButton *FromVideo = new wxButton(this,BUTTON_DEST_FROM_VIDEO,_("From video"));
if (!vid->loaded) FromVideo->Enable(false);
if (!VideoContext::Get()->IsLoaded()) FromVideo->Enable(false);
ResSizer->Add(ResX,1,wxRIGHT,5);
ResSizer->Add(ResText,0,wxALIGN_CENTER | wxRIGHT,5);
ResSizer->Add(ResY,1,wxRIGHT,5);
@ -244,8 +244,8 @@ void DialogResample::OnResample (wxCommandEvent &event) {
/////////////////////////////////////////
// Get destination resolution from video
void DialogResample::OnGetDestRes (wxCommandEvent &event) {
ResX->SetValue(wxString::Format(_T("%i"),vid->provider->GetSourceWidth()));
ResY->SetValue(wxString::Format(_T("%i"),vid->provider->GetSourceHeight()));
ResX->SetValue(wxString::Format(_T("%i"),VideoContext::Get()->GetWidth()));
ResY->SetValue(wxString::Format(_T("%i"),VideoContext::Get()->GetHeight()));
}

View file

@ -57,7 +57,7 @@ wxDialog (parent, -1, _("Styling assistant"), wxDefaultPosition, wxDefaultSize,
{