mirror of
https://github.com/cookiengineer/audacity
synced 2025-10-26 00:03:52 +02:00
... Unnecessary because transitively included. But each .cpp file still includes its own .h file near the top to ensure that it compiles indenendently, even if it is reincluded transitively later.
2075 lines
65 KiB
C++
2075 lines
65 KiB
C++
/**********************************************************************
|
|
|
|
Audacity: A Digital Audio Editor
|
|
|
|
ExportFFmpegDialogs.cpp
|
|
|
|
Audacity(R) is copyright (c) 1999-2010 Audacity Team.
|
|
License: GPL v2. See License.txt.
|
|
|
|
LRN
|
|
|
|
******************************************************************//**
|
|
|
|
\class ExportFFmpegAC3Options
|
|
\brief Options dialog for FFmpeg exporting of AC3 format.
|
|
|
|
*//***************************************************************//**
|
|
|
|
\class ExportFFmpegAACOptions
|
|
\brief Options dialog for FFmpeg exporting of AAC format.
|
|
|
|
*//***************************************************************//**
|
|
|
|
\class ExportFFmpegAMRNBOptions
|
|
\brief Options dialog for FFmpeg exporting of AMRNB format.
|
|
|
|
*//***************************************************************//**
|
|
|
|
\class ExportFFmpegWMAOptions
|
|
\brief Options dialog for FFmpeg exporting of WMA format.
|
|
|
|
*//***************************************************************//**
|
|
|
|
\class ExportFFmpegOptions
|
|
\brief Options dialog for Custom FFmpeg export format.
|
|
|
|
*//*******************************************************************/
|
|
|
|
#include "../Audacity.h" // keep ffmpeg before wx because they interact // for USE_* macros
|
|
#include "ExportFFmpegDialogs.h"
|
|
|
|
#include "../FFmpeg.h" // and Audacity.h before FFmpeg for config*.h
|
|
|
|
#include <wx/checkbox.h>
|
|
#include <wx/choice.h>
|
|
#include <wx/intl.h>
|
|
#include <wx/timer.h>
|
|
#include <wx/progdlg.h>
|
|
#include <wx/string.h>
|
|
#include <wx/textctrl.h>
|
|
#include <wx/listbox.h>
|
|
#include <wx/window.h>
|
|
#include <wx/spinctrl.h>
|
|
#include <wx/combobox.h>
|
|
#include <wx/stattext.h>
|
|
|
|
#include <FileDialog.h>
|
|
|
|
#include "../FileFormats.h"
|
|
#include "../Mix.h"
|
|
#include "../Project.h"
|
|
#include "../Tags.h"
|
|
#include "../TranslatableStringArray.h"
|
|
#include "../widgets/ErrorDialog.h"
|
|
|
|
#include "Export.h"
|
|
|
|
#if defined(USE_FFMPEG)
|
|
|
|
extern FFmpegLibs *FFmpegLibsInst();
|
|
|
|
/// This construction defines a enumeration of UI element IDs, and a static
|
|
/// array of their string representations (this way they're always synchronized).
|
|
/// Do not store the enumerated values in external files, as they may change;
|
|
/// the strings may be stored.
|
|
#define FFMPEG_EXPORT_CTRL_ID_ENTRIES \
|
|
FFMPEG_EXPORT_CTRL_ID_FIRST_ENTRY(FEFirstID, 20000), \
|
|
FFMPEG_EXPORT_CTRL_ID_ENTRY(FEFormatID), \
|
|
FFMPEG_EXPORT_CTRL_ID_ENTRY(FECodecID), \
|
|
FFMPEG_EXPORT_CTRL_ID_ENTRY(FEBitrateID), \
|
|
FFMPEG_EXPORT_CTRL_ID_ENTRY(FEQualityID), \
|
|
FFMPEG_EXPORT_CTRL_ID_ENTRY(FESampleRateID), \
|
|
FFMPEG_EXPORT_CTRL_ID_ENTRY(FELanguageID), \
|
|
FFMPEG_EXPORT_CTRL_ID_ENTRY(FETagID), \
|
|
FFMPEG_EXPORT_CTRL_ID_ENTRY(FECutoffID), \
|
|
FFMPEG_EXPORT_CTRL_ID_ENTRY(FEFrameSizeID), \
|
|
FFMPEG_EXPORT_CTRL_ID_ENTRY(FEBufSizeID), \
|
|
FFMPEG_EXPORT_CTRL_ID_ENTRY(FEProfileID), \
|
|
FFMPEG_EXPORT_CTRL_ID_ENTRY(FECompLevelID), \
|
|
FFMPEG_EXPORT_CTRL_ID_ENTRY(FEUseLPCID), \
|
|
FFMPEG_EXPORT_CTRL_ID_ENTRY(FELPCCoeffsID), \
|
|
FFMPEG_EXPORT_CTRL_ID_ENTRY(FEMinPredID), \
|
|
FFMPEG_EXPORT_CTRL_ID_ENTRY(FEMaxPredID), \
|
|
FFMPEG_EXPORT_CTRL_ID_ENTRY(FEPredOrderID), \
|
|
FFMPEG_EXPORT_CTRL_ID_ENTRY(FEMinPartOrderID), \
|
|
FFMPEG_EXPORT_CTRL_ID_ENTRY(FEMaxPartOrderID), \
|
|
FFMPEG_EXPORT_CTRL_ID_ENTRY(FEMuxRateID), \
|
|
FFMPEG_EXPORT_CTRL_ID_ENTRY(FEPacketSizeID), \
|
|
FFMPEG_EXPORT_CTRL_ID_ENTRY(FEBitReservoirID), \
|
|
FFMPEG_EXPORT_CTRL_ID_ENTRY(FEVariableBlockLenID), \
|
|
FFMPEG_EXPORT_CTRL_ID_ENTRY(FELastID), \
|
|
\
|
|
FFMPEG_EXPORT_CTRL_ID_ENTRY(FEFormatLabelID), \
|
|
FFMPEG_EXPORT_CTRL_ID_ENTRY(FECodecLabelID), \
|
|
FFMPEG_EXPORT_CTRL_ID_ENTRY(FEFormatNameID), \
|
|
FFMPEG_EXPORT_CTRL_ID_ENTRY(FECodecNameID), \
|
|
FFMPEG_EXPORT_CTRL_ID_ENTRY(FEPresetID), \
|
|
FFMPEG_EXPORT_CTRL_ID_ENTRY(FESavePresetID), \
|
|
FFMPEG_EXPORT_CTRL_ID_ENTRY(FELoadPresetID), \
|
|
FFMPEG_EXPORT_CTRL_ID_ENTRY(FEDeletePresetID), \
|
|
FFMPEG_EXPORT_CTRL_ID_ENTRY(FEAllFormatsID), \
|
|
FFMPEG_EXPORT_CTRL_ID_ENTRY(FEAllCodecsID), \
|
|
FFMPEG_EXPORT_CTRL_ID_ENTRY(FEImportPresetsID), \
|
|
FFMPEG_EXPORT_CTRL_ID_ENTRY(FEExportPresetsID) \
|
|
|
|
// First the enumeration
|
|
#define FFMPEG_EXPORT_CTRL_ID_FIRST_ENTRY(name, num) name = num
|
|
#define FFMPEG_EXPORT_CTRL_ID_ENTRY(name) name
|
|
|
|
enum FFmpegExportCtrlID {
|
|
FFMPEG_EXPORT_CTRL_ID_ENTRIES
|
|
};
|
|
|
|
// Now the string representations
|
|
#undef FFMPEG_EXPORT_CTRL_ID_FIRST_ENTRY
|
|
#define FFMPEG_EXPORT_CTRL_ID_FIRST_ENTRY(name, num) wxT(#name)
|
|
#undef FFMPEG_EXPORT_CTRL_ID_ENTRY
|
|
#define FFMPEG_EXPORT_CTRL_ID_ENTRY(name) wxT(#name)
|
|
static const wxChar *FFmpegExportCtrlIDNames[] = {
|
|
FFMPEG_EXPORT_CTRL_ID_ENTRIES
|
|
};
|
|
|
|
#undef FFMPEG_EXPORT_CTRL_ID_ENTRIES
|
|
#undef FFMPEG_EXPORT_CTRL_ID_ENTRY
|
|
#undef FFMPEG_EXPORT_CTRL_ID_FIRST_ENTRY
|
|
|
|
//----------------------------------------------------------------------------
|
|
// ExportFFmpegAC3Options Class
|
|
//----------------------------------------------------------------------------
|
|
|
|
// This initialises content for the static const member variables defined in
|
|
// ExportFFmpegDialogs.h (note no static keyword - important!)
|
|
const int ExportFFmpegAC3Options::iAC3BitRates[] = { 32000, 40000, 48000, 56000, 64000, 80000, 96000, 112000, 128000, 160000, 192000, 224000, 256000, 320000, 384000, 448000, 512000, 576000, 640000 };
|
|
const int ExportFFmpegAC3Options::iAC3SampleRates[] = { 32000, 44100, 48000, 0 };
|
|
|
|
ExportFFmpegAC3Options::ExportFFmpegAC3Options(wxWindow *parent, int WXUNUSED(format))
|
|
: wxPanelWrapper(parent, wxID_ANY)
|
|
{
|
|
for (unsigned int i=0; i < (sizeof(iAC3BitRates)/sizeof(int)); i++)
|
|
{
|
|
mBitRateNames.push_back(wxString::Format(_("%i kbps"),iAC3BitRates[i]/1000));
|
|
mBitRateLabels.push_back(iAC3BitRates[i]);
|
|
}
|
|
|
|
ShuttleGui S(this, eIsCreatingFromPrefs);
|
|
PopulateOrExchange(S);
|
|
|
|
TransferDataToWindow();
|
|
}
|
|
|
|
ExportFFmpegAC3Options::~ExportFFmpegAC3Options()
|
|
{
|
|
TransferDataFromWindow();
|
|
}
|
|
|
|
///
|
|
///
|
|
void ExportFFmpegAC3Options::PopulateOrExchange(ShuttleGui & S)
|
|
{
|
|
S.StartVerticalLay();
|
|
{
|
|
S.StartHorizontalLay(wxCENTER);
|
|
{
|
|
S.StartMultiColumn(2, wxCENTER);
|
|
{
|
|
S.TieChoice(_("Bit Rate:"), wxT("/FileFormats/AC3BitRate"),
|
|
160000, mBitRateNames, mBitRateLabels);
|
|
}
|
|
S.EndMultiColumn();
|
|
}
|
|
S.EndHorizontalLay();
|
|
}
|
|
S.EndVerticalLay();
|
|
}
|
|
|
|
///
|
|
///
|
|
bool ExportFFmpegAC3Options::TransferDataToWindow()
|
|
{
|
|
return true;
|
|
}
|
|
|
|
///
|
|
///
|
|
bool ExportFFmpegAC3Options::TransferDataFromWindow()
|
|
{
|
|
ShuttleGui S(this, eIsSavingToPrefs);
|
|
PopulateOrExchange(S);
|
|
|
|
gPrefs->Flush();
|
|
|
|
return true;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
// ExportFFmpegAACOptions Class
|
|
//----------------------------------------------------------------------------
|
|
|
|
ExportFFmpegAACOptions::ExportFFmpegAACOptions(wxWindow *parent, int WXUNUSED(format))
|
|
: wxPanelWrapper(parent, wxID_ANY)
|
|
{
|
|
ShuttleGui S(this, eIsCreatingFromPrefs);
|
|
PopulateOrExchange(S);
|
|
|
|
TransferDataToWindow();
|
|
}
|
|
|
|
ExportFFmpegAACOptions::~ExportFFmpegAACOptions()
|
|
{
|
|
TransferDataFromWindow();
|
|
}
|
|
|
|
///
|
|
///
|
|
void ExportFFmpegAACOptions::PopulateOrExchange(ShuttleGui & S)
|
|
{
|
|
S.StartVerticalLay();
|
|
{
|
|
S.StartHorizontalLay(wxEXPAND);
|
|
{
|
|
S.SetSizerProportion(1);
|
|
S.StartMultiColumn(2, wxCENTER);
|
|
{
|
|
S.SetStretchyCol(1);
|
|
S.Prop(1).TieSlider(_("Quality:"),wxT("/FileFormats/AACQuality"),100,500,10);
|
|
}
|
|
S.EndMultiColumn();
|
|
}
|
|
S.EndHorizontalLay();
|
|
}
|
|
S.EndVerticalLay();
|
|
}
|
|
|
|
///
|
|
///
|
|
bool ExportFFmpegAACOptions::TransferDataToWindow()
|
|
{
|
|
return true;
|
|
}
|
|
|
|
///
|
|
///
|
|
bool ExportFFmpegAACOptions::TransferDataFromWindow()
|
|
{
|
|
ShuttleGui S(this, eIsSavingToPrefs);
|
|
PopulateOrExchange(S);
|
|
|
|
gPrefs->Flush();
|
|
|
|
return true;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
// ExportFFmpegAMRNBOptions Class
|
|
//----------------------------------------------------------------------------
|
|
|
|
/// Bit Rates supported by libAMR-NB encoder
|
|
/// Sample Rate is always 8 kHz
|
|
int ExportFFmpegAMRNBOptions::iAMRNBBitRate[] =
|
|
{ 4750, 5150, 5900, 6700, 7400, 7950, 10200, 12200 };
|
|
|
|
ExportFFmpegAMRNBOptions::ExportFFmpegAMRNBOptions(wxWindow *parent, int WXUNUSED(format))
|
|
: wxPanelWrapper(parent, wxID_ANY)
|
|
{
|
|
for (unsigned int i=0; i < (sizeof(iAMRNBBitRate)/sizeof(int)); i++)
|
|
{
|
|
mBitRateNames.push_back(wxString::Format(_("%.2f kbps"),(float)iAMRNBBitRate[i]/1000));
|
|
mBitRateLabels.push_back(iAMRNBBitRate[i]);
|
|
}
|
|
|
|
ShuttleGui S(this, eIsCreatingFromPrefs);
|
|
PopulateOrExchange(S);
|
|
|
|
TransferDataToWindow();
|
|
}
|
|
|
|
ExportFFmpegAMRNBOptions::~ExportFFmpegAMRNBOptions()
|
|
{
|
|
TransferDataFromWindow();
|
|
}
|
|
|
|
///
|
|
///
|
|
void ExportFFmpegAMRNBOptions::PopulateOrExchange(ShuttleGui & S)
|
|
{
|
|
S.StartVerticalLay();
|
|
{
|
|
S.StartHorizontalLay(wxCENTER);
|
|
{
|
|
S.StartMultiColumn(2, wxCENTER);
|
|
{
|
|
S.TieChoice(_("Bit Rate:"), wxT("/FileFormats/AMRNBBitRate"),
|
|
12200, mBitRateNames, mBitRateLabels);
|
|
}
|
|
S.EndMultiColumn();
|
|
}
|
|
S.EndHorizontalLay();
|
|
}
|
|
S.EndVerticalLay();
|
|
}
|
|
|
|
///
|
|
///
|
|
bool ExportFFmpegAMRNBOptions::TransferDataToWindow()
|
|
{
|
|
return true;
|
|
}
|
|
|
|
///
|
|
///
|
|
bool ExportFFmpegAMRNBOptions::TransferDataFromWindow()
|
|
{
|
|
ShuttleGui S(this, eIsSavingToPrefs);
|
|
PopulateOrExchange(S);
|
|
|
|
gPrefs->Flush();
|
|
|
|
return true;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
// ExportFFmpegWMAOptions Class
|
|
//----------------------------------------------------------------------------
|
|
|
|
const int ExportFFmpegWMAOptions::iWMASampleRates[] =
|
|
{ 8000, 11025, 16000, 22050, 44100, 0};
|
|
|
|
/// Bit Rates supported by WMA encoder. Setting bit rate to other values will not result in different file size.
|
|
const int ExportFFmpegWMAOptions::iWMABitRate[] =
|
|
{ 24000, 32000, 40000, 48000, 64000, 80000, 96000, 128000, 160000, 192000, 256000, 320000 };
|
|
|
|
ExportFFmpegWMAOptions::ExportFFmpegWMAOptions(wxWindow *parent, int WXUNUSED(format))
|
|
: wxPanelWrapper(parent, wxID_ANY)
|
|
{
|
|
for (unsigned int i=0; i < (sizeof(iWMABitRate)/sizeof(int)); i++)
|
|
{
|
|
/* i18n-hint: abbreviates thousands of bits per second */
|
|
mBitRateNames.push_back(wxString::Format(_("%i kbps"),iWMABitRate[i]/1000));
|
|
mBitRateLabels.push_back(iWMABitRate[i]);
|
|
}
|
|
|
|
ShuttleGui S(this, eIsCreatingFromPrefs);
|
|
PopulateOrExchange(S);
|
|
|
|
TransferDataToWindow();
|
|
}
|
|
|
|
ExportFFmpegWMAOptions::~ExportFFmpegWMAOptions()
|
|
{
|
|
TransferDataFromWindow();
|
|
}
|
|
|
|
///
|
|
///
|
|
void ExportFFmpegWMAOptions::PopulateOrExchange(ShuttleGui & S)
|
|
{
|
|
S.StartVerticalLay();
|
|
{
|
|
S.StartHorizontalLay(wxCENTER);
|
|
{
|
|
S.StartMultiColumn(2, wxCENTER);
|
|
{
|
|
S.TieChoice(_("Bit Rate:"), wxT("/FileFormats/WMABitRate"),
|
|
128000, mBitRateNames, mBitRateLabels);
|
|
}
|
|
S.EndMultiColumn();
|
|
}
|
|
S.EndHorizontalLay();
|
|
}
|
|
S.EndVerticalLay();
|
|
}
|
|
|
|
///
|
|
///
|
|
bool ExportFFmpegWMAOptions::TransferDataToWindow()
|
|
{
|
|
return true;
|
|
}
|
|
|
|
///
|
|
///
|
|
bool ExportFFmpegWMAOptions::TransferDataFromWindow()
|
|
{
|
|
ShuttleGui S(this, eIsSavingToPrefs);
|
|
PopulateOrExchange(S);
|
|
|
|
gPrefs->Flush();
|
|
|
|
return true;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
// ExportFFmpegCustomOptions Class
|
|
//----------------------------------------------------------------------------
|
|
|
|
#define OpenID 9000
|
|
|
|
BEGIN_EVENT_TABLE(ExportFFmpegCustomOptions, wxPanelWrapper)
|
|
EVT_BUTTON(OpenID, ExportFFmpegCustomOptions::OnOpen)
|
|
END_EVENT_TABLE()
|
|
|
|
ExportFFmpegCustomOptions::ExportFFmpegCustomOptions(wxWindow *parent, int WXUNUSED(format))
|
|
: wxPanelWrapper(parent, wxID_ANY)
|
|
{
|
|
ShuttleGui S(this, eIsCreatingFromPrefs);
|
|
PopulateOrExchange(S);
|
|
|
|
TransferDataToWindow();
|
|
}
|
|
|
|
ExportFFmpegCustomOptions::~ExportFFmpegCustomOptions()
|
|
{
|
|
TransferDataFromWindow();
|
|
}
|
|
|
|
///
|
|
///
|
|
void ExportFFmpegCustomOptions::PopulateOrExchange(ShuttleGui & S)
|
|
{
|
|
S.StartHorizontalLay(wxCENTER);
|
|
{
|
|
S.StartHorizontalLay(wxCENTER, 0);
|
|
{
|
|
S.Id(OpenID).AddButton(_("Open custom FFmpeg format options"));
|
|
}
|
|
S.EndHorizontalLay();
|
|
}
|
|
S.EndHorizontalLay();
|
|
}
|
|
|
|
///
|
|
///
|
|
bool ExportFFmpegCustomOptions::TransferDataToWindow()
|
|
{
|
|
return true;
|
|
}
|
|
|
|
///
|
|
///
|
|
bool ExportFFmpegCustomOptions::TransferDataFromWindow()
|
|
{
|
|
return true;
|
|
}
|
|
|
|
///
|
|
///
|
|
void ExportFFmpegCustomOptions::OnOpen(wxCommandEvent & WXUNUSED(evt))
|
|
{
|
|
// Show "Locate FFmpeg" dialog
|
|
PickFFmpegLibs();
|
|
if (!FFmpegLibsInst()->ValidLibsLoaded())
|
|
{
|
|
FFmpegLibsInst()->FindLibs(NULL);
|
|
FFmpegLibsInst()->FreeLibs();
|
|
if (!LoadFFmpeg(true))
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
DropFFmpegLibs();
|
|
auto pWin = wxTheApp->GetTopWindow();
|
|
ExportFFmpegOptions od(pWin);
|
|
od.ShowModal();
|
|
}
|
|
|
|
FFmpegPreset::FFmpegPreset()
|
|
{
|
|
mControlState.resize(FELastID - FEFirstID);
|
|
}
|
|
|
|
FFmpegPreset::~FFmpegPreset()
|
|
{
|
|
}
|
|
|
|
FFmpegPresets::FFmpegPresets()
|
|
{
|
|
mPreset = NULL;
|
|
mAbortImport = false;
|
|
|
|
XMLFileReader xmlfile;
|
|
wxFileName xmlFileName(FileNames::DataDir(), wxT("ffmpeg_presets.xml"));
|
|
xmlfile.Parse(this,xmlFileName.GetFullPath());
|
|
}
|
|
|
|
FFmpegPresets::~FFmpegPresets()
|
|
{
|
|
// We're in a destructor! Don't let exceptions out!
|
|
GuardedCall( [&] {
|
|
wxFileName xmlFileName{ FileNames::DataDir(), wxT("ffmpeg_presets.xml") };
|
|
XMLFileWriter writer{
|
|
xmlFileName.GetFullPath(), _("Error Saving FFmpeg Presets") };
|
|
WriteXMLHeader(writer);
|
|
WriteXML(writer);
|
|
writer.Commit();
|
|
} );
|
|
}
|
|
|
|
void FFmpegPresets::ImportPresets(wxString &filename)
|
|
{
|
|
mPreset = NULL;
|
|
mAbortImport = false;
|
|
|
|
FFmpegPresetMap savePresets = mPresets;
|
|
|
|
XMLFileReader xmlfile;
|
|
bool success = xmlfile.Parse(this,filename);
|
|
if (!success || mAbortImport) {
|
|
mPresets = savePresets;
|
|
}
|
|
}
|
|
|
|
void FFmpegPresets::ExportPresets(wxString &filename)
|
|
{
|
|
GuardedCall( [&] {
|
|
XMLFileWriter writer{ filename, _("Error Saving FFmpeg Presets") };
|
|
WriteXMLHeader(writer);
|
|
WriteXML(writer);
|
|
writer.Commit();
|
|
} );
|
|
}
|
|
|
|
void FFmpegPresets::GetPresetList(wxArrayString &list)
|
|
{
|
|
list.clear();
|
|
FFmpegPresetMap::iterator iter;
|
|
for (iter = mPresets.begin(); iter != mPresets.end(); ++iter)
|
|
{
|
|
list.push_back(iter->second.mPresetName);
|
|
}
|
|
|
|
std::sort( list.begin(), list.end() );
|
|
}
|
|
|
|
void FFmpegPresets::DeletePreset(wxString &name)
|
|
{
|
|
FFmpegPresetMap::iterator iter = mPresets.find(name);
|
|
if (iter != mPresets.end())
|
|
{
|
|
mPresets.erase(iter);
|
|
}
|
|
}
|
|
|
|
FFmpegPreset *FFmpegPresets::FindPreset(wxString &name)
|
|
{
|
|
FFmpegPresetMap::iterator iter = mPresets.find(name);
|
|
if (iter != mPresets.end())
|
|
{
|
|
return &iter->second;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
void FFmpegPresets::SavePreset(ExportFFmpegOptions *parent, wxString &name)
|
|
{
|
|
wxString format;
|
|
wxString codec;
|
|
FFmpegPreset *preset = FindPreset(name);
|
|
if (preset)
|
|
{
|
|
wxString query = wxString::Format(_("Overwrite preset '%s'?"),name);
|
|
int action = AudacityMessageBox(query,_("Confirm Overwrite"),wxYES_NO | wxCENTRE);
|
|
if (action == wxNO) return;
|
|
}
|
|
|
|
{
|
|
wxWindow *wnd;
|
|
wxListBox *lb;
|
|
|
|
wnd = dynamic_cast<wxWindow*>(parent)->FindWindowById(FEFormatID,parent);
|
|
lb = dynamic_cast<wxListBox*>(wnd);
|
|
if (lb->GetSelection() < 0)
|
|
{
|
|
AudacityMessageBox(_("Please select format before saving a profile"));
|
|
return;
|
|
}
|
|
format = lb->GetStringSelection();
|
|
|
|
wnd = dynamic_cast<wxWindow*>(parent)->FindWindowById(FECodecID,parent);
|
|
lb = dynamic_cast<wxListBox*>(wnd);
|
|
if (lb->GetSelection() < 0)
|
|
{
|
|
AudacityMessageBox(_("Please select codec before saving a profile"));
|
|
return;
|
|
}
|
|
codec = lb->GetStringSelection();
|
|
}
|
|
|
|
preset = &mPresets[name];
|
|
preset->mPresetName = name;
|
|
|
|
wxSpinCtrl *sc;
|
|
wxTextCtrl *tc;
|
|
wxCheckBox *cb;
|
|
wxChoice *ch;
|
|
|
|
for (int id = FEFirstID; id < FELastID; id++)
|
|
{
|
|
wxWindow *wnd = dynamic_cast<wxWindow*>(parent)->FindWindowById(id,parent);
|
|
if (wnd != NULL)
|
|
{
|
|
switch(id)
|
|
{
|
|
case FEFormatID:
|
|
preset->mControlState[id - FEFirstID] = format;
|
|
break;
|
|
case FECodecID:
|
|
preset->mControlState[id - FEFirstID] = codec;
|
|
break;
|
|
// Spin control
|
|
case FEBitrateID:
|
|
case FEQualityID:
|
|
case FESampleRateID:
|
|
case FECutoffID:
|
|
case FEFrameSizeID:
|
|
case FEBufSizeID:
|
|
case FECompLevelID:
|
|
case FELPCCoeffsID:
|
|
case FEMinPredID:
|
|
case FEMaxPredID:
|
|
case FEMinPartOrderID:
|
|
case FEMaxPartOrderID:
|
|
case FEMuxRateID:
|
|
case FEPacketSizeID:
|
|
sc = dynamic_cast<wxSpinCtrl*>(wnd);
|
|
preset->mControlState[id - FEFirstID] = wxString::Format(wxT("%d"),sc->GetValue());
|
|
break;
|
|
// Text control
|
|
case FELanguageID:
|
|
case FETagID:
|
|
tc = dynamic_cast<wxTextCtrl*>(wnd);
|
|
preset->mControlState[id - FEFirstID] = tc->GetValue();
|
|
break;
|
|
// Choice
|
|
case FEProfileID:
|
|
case FEPredOrderID:
|
|
ch = dynamic_cast<wxChoice*>(wnd);
|
|
preset->mControlState[id - FEFirstID] = wxString::Format(wxT("%d"),ch->GetSelection());
|
|
break;
|
|
// Check box
|
|
case FEUseLPCID:
|
|
case FEBitReservoirID:
|
|
case FEVariableBlockLenID:
|
|
cb = dynamic_cast<wxCheckBox*>(wnd);
|
|
preset->mControlState[id - FEFirstID] = wxString::Format(wxT("%d"),cb->GetValue());
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void FFmpegPresets::LoadPreset(ExportFFmpegOptions *parent, wxString &name)
|
|
{
|
|
FFmpegPreset *preset = FindPreset(name);
|
|
if (!preset)
|
|
{
|
|
AudacityMessageBox(wxString::Format(_("Preset '%s' does not exist."),name));
|
|
return;
|
|
}
|
|
|
|
wxListBox *lb;
|
|
wxSpinCtrl *sc;
|
|
wxTextCtrl *tc;
|
|
wxCheckBox *cb;
|
|
wxChoice *ch;
|
|
|
|
for (int id = FEFirstID; id < FELastID; id++)
|
|
{
|
|
wxWindow *wnd = parent->FindWindowById(id,parent);
|
|
if (wnd != NULL)
|
|
{
|
|
wxString readstr;
|
|
long readlong;
|
|
bool readbool;
|
|
switch(id)
|
|
{
|
|
// Listbox
|
|
case FEFormatID:
|
|
case FECodecID:
|
|
lb = dynamic_cast<wxListBox*>(wnd);
|
|
readstr = preset->mControlState[id - FEFirstID];
|
|
readlong = lb->FindString(readstr);
|
|
if (readlong > -1) lb->Select(readlong);
|
|
break;
|
|
// Spin control
|
|
case FEBitrateID:
|
|
case FEQualityID:
|
|
case FESampleRateID:
|
|
case FECutoffID:
|
|
case FEFrameSizeID:
|
|
case FEBufSizeID:
|
|
case FECompLevelID:
|
|
case FELPCCoeffsID:
|
|
case FEMinPredID:
|
|
case FEMaxPredID:
|
|
case FEMinPartOrderID:
|
|
case FEMaxPartOrderID:
|
|
case FEMuxRateID:
|
|
case FEPacketSizeID:
|
|
sc = dynamic_cast<wxSpinCtrl*>(wnd);
|
|
preset->mControlState[id - FEFirstID].ToLong(&readlong);
|
|
sc->SetValue(readlong);
|
|
break;
|
|
// Text control
|
|
case FELanguageID:
|
|
case FETagID:
|
|
tc = dynamic_cast<wxTextCtrl*>(wnd);
|
|
tc->SetValue(preset->mControlState[id - FEFirstID]);
|
|
break;
|
|
// Choice
|
|
case FEProfileID:
|
|
case FEPredOrderID:
|
|
ch = dynamic_cast<wxChoice*>(wnd);
|
|
preset->mControlState[id - FEFirstID].ToLong(&readlong);
|
|
if (readlong > -1) ch->Select(readlong);
|
|
break;
|
|
// Check box
|
|
case FEUseLPCID:
|
|
case FEBitReservoirID:
|
|
case FEVariableBlockLenID:
|
|
cb = dynamic_cast<wxCheckBox*>(wnd);
|
|
preset->mControlState[id - FEFirstID].ToLong(&readlong);
|
|
if (readlong) readbool = true; else readbool = false;
|
|
cb->SetValue(readbool);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
bool FFmpegPresets::HandleXMLTag(const wxChar *tag, const wxChar **attrs)
|
|
{
|
|
if (mAbortImport)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (!wxStrcmp(tag,wxT("ffmpeg_presets")))
|
|
{
|
|
return true;
|
|
}
|
|
|
|
if (!wxStrcmp(tag,wxT("preset")))
|
|
{
|
|
while (*attrs)
|
|
{
|
|
const wxChar *attr = *attrs++;
|
|
wxString value = *attrs++;
|
|
|
|
if (!value)
|
|
break;
|
|
|
|
if (!wxStrcmp(attr,wxT("name")))
|
|
{
|
|
mPreset = FindPreset(value);
|
|
if (mPreset)
|
|
{
|
|
wxString query = wxString::Format(_("Replace preset '%s'?"), value);
|
|
int action = AudacityMessageBox(query, _("Confirm Overwrite"), wxYES_NO | wxCANCEL | wxCENTRE);
|
|
if (action == wxCANCEL)
|
|
{
|
|
mAbortImport = true;
|
|
return false;
|
|
}
|
|
if (action == wxNO)
|
|
{
|
|
mPreset = NULL;
|
|
return false;
|
|
}
|
|
*mPreset = FFmpegPreset();
|
|
}
|
|
else
|
|
{
|
|
mPreset = &mPresets[value];
|
|
}
|
|
mPreset->mPresetName = value;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
if (!wxStrcmp(tag,wxT("setctrlstate")) && mPreset)
|
|
{
|
|
long id = -1;
|
|
while (*attrs)
|
|
{
|
|
const wxChar *attr = *attrs++;
|
|
const wxChar *value = *attrs++;
|
|
|
|
if (!value)
|
|
break;
|
|
|
|
if (!wxStrcmp(attr,wxT("id")))
|
|
{
|
|
for (long i = FEFirstID; i < FELastID; i++)
|
|
if (!wxStrcmp(FFmpegExportCtrlIDNames[i - FEFirstID],value))
|
|
id = i;
|
|
}
|
|
else if (!wxStrcmp(attr,wxT("state")))
|
|
{
|
|
if (id > FEFirstID && id < FELastID)
|
|
mPreset->mControlState[id - FEFirstID] = wxString(value);
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
XMLTagHandler *FFmpegPresets::HandleXMLChild(const wxChar *tag)
|
|
{
|
|
if (mAbortImport)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
if (!wxStrcmp(tag, wxT("preset")))
|
|
{
|
|
return this;
|
|
}
|
|
else if (!wxStrcmp(tag, wxT("setctrlstate")))
|
|
{
|
|
return this;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
void FFmpegPresets::WriteXMLHeader(XMLWriter &xmlFile) const
|
|
// may throw
|
|
{
|
|
xmlFile.Write(wxT("<?xml "));
|
|
xmlFile.Write(wxT("version=\"1.0\" "));
|
|
xmlFile.Write(wxT("standalone=\"no\" "));
|
|
xmlFile.Write(wxT("?>\n"));
|
|
|
|
wxString dtdName = wxT("-//audacityffmpegpreset-1.0.0//DTD//EN");
|
|
wxString dtdURI =
|
|
wxT("http://audacity.sourceforge.net/xml/audacityffmpegpreset-1.0.0.dtd");
|
|
|
|
xmlFile.Write(wxT("<!DOCTYPE "));
|
|
xmlFile.Write(wxT("project "));
|
|
xmlFile.Write(wxT("PUBLIC "));
|
|
xmlFile.Write(wxT("\"-//audacityffmpegpreset-1.0.0//DTD//EN\" "));
|
|
xmlFile.Write(wxT("\"http://audacity.sourceforge.net/xml/audacityffmpegpreset-1.0.0.dtd\" "));
|
|
xmlFile.Write(wxT(">\n"));
|
|
}
|
|
|
|
void FFmpegPresets::WriteXML(XMLWriter &xmlFile) const
|
|
// may throw
|
|
{
|
|
xmlFile.StartTag(wxT("ffmpeg_presets"));
|
|
xmlFile.WriteAttr(wxT("version"),wxT("1.0"));
|
|
FFmpegPresetMap::const_iterator iter;
|
|
for (iter = mPresets.begin(); iter != mPresets.end(); ++iter)
|
|
{
|
|
auto preset = &iter->second;
|
|
xmlFile.StartTag(wxT("preset"));
|
|
xmlFile.WriteAttr(wxT("name"),preset->mPresetName);
|
|
for (long i = FEFirstID + 1; i < FELastID; i++)
|
|
{
|
|
xmlFile.StartTag(wxT("setctrlstate"));
|
|
xmlFile.WriteAttr(wxT("id"),wxString(FFmpegExportCtrlIDNames[i - FEFirstID]));
|
|
xmlFile.WriteAttr(wxT("state"),preset->mControlState[i - FEFirstID]);
|
|
xmlFile.EndTag(wxT("setctrlstate"));
|
|
}
|
|
xmlFile.EndTag(wxT("preset"));
|
|
}
|
|
xmlFile.EndTag(wxT("ffmpeg_presets"));
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
// ExportFFmpegOptions Class
|
|
//----------------------------------------------------------------------------
|
|
|
|
BEGIN_EVENT_TABLE(ExportFFmpegOptions, wxDialogWrapper)
|
|
EVT_BUTTON(wxID_OK,ExportFFmpegOptions::OnOK)
|
|
EVT_LISTBOX(FEFormatID,ExportFFmpegOptions::OnFormatList)
|
|
EVT_LISTBOX(FECodecID,ExportFFmpegOptions::OnCodecList)
|
|
EVT_BUTTON(FEAllFormatsID,ExportFFmpegOptions::OnAllFormats)
|
|
EVT_BUTTON(FEAllCodecsID,ExportFFmpegOptions::OnAllCodecs)
|
|
EVT_BUTTON(FESavePresetID,ExportFFmpegOptions::OnSavePreset)
|
|
EVT_BUTTON(FELoadPresetID,ExportFFmpegOptions::OnLoadPreset)
|
|
EVT_BUTTON(FEDeletePresetID,ExportFFmpegOptions::OnDeletePreset)
|
|
EVT_BUTTON(FEImportPresetsID,ExportFFmpegOptions::OnImportPresets)
|
|
EVT_BUTTON(FEExportPresetsID,ExportFFmpegOptions::OnExportPresets)
|
|
END_EVENT_TABLE()
|
|
|
|
/// Format-codec compatibility list
|
|
/// Must end with NULL entry
|
|
CompatibilityEntry ExportFFmpegOptions::CompatibilityList[] =
|
|
{
|
|
{ wxT("adts"), AV_CODEC_ID_AAC },
|
|
|
|
{ wxT("aiff"), AV_CODEC_ID_PCM_S16BE },
|
|
{ wxT("aiff"), AV_CODEC_ID_PCM_S8 },
|
|
{ wxT("aiff"), AV_CODEC_ID_PCM_S24BE },
|
|
{ wxT("aiff"), AV_CODEC_ID_PCM_S32BE },
|
|
{ wxT("aiff"), AV_CODEC_ID_PCM_ALAW },
|
|
{ wxT("aiff"), AV_CODEC_ID_PCM_MULAW },
|
|
{ wxT("aiff"), AV_CODEC_ID_MACE3 },
|
|
{ wxT("aiff"), AV_CODEC_ID_MACE6 },
|
|
{ wxT("aiff"), AV_CODEC_ID_GSM },
|
|
{ wxT("aiff"), AV_CODEC_ID_ADPCM_G726 },
|
|
{ wxT("aiff"), AV_CODEC_ID_PCM_S16LE },
|
|
{ wxT("aiff"), AV_CODEC_ID_ADPCM_IMA_QT },
|
|
{ wxT("aiff"), AV_CODEC_ID_QDM2 },
|
|
|
|
{ wxT("amr"), AV_CODEC_ID_AMR_NB },
|
|
{ wxT("amr"), AV_CODEC_ID_AMR_WB },
|
|
|
|
{ wxT("asf"), AV_CODEC_ID_PCM_S16LE },
|
|
{ wxT("asf"), AV_CODEC_ID_PCM_U8 },
|
|
{ wxT("asf"), AV_CODEC_ID_PCM_S24LE },
|
|
{ wxT("asf"), AV_CODEC_ID_PCM_S32LE },
|
|
{ wxT("asf"), AV_CODEC_ID_ADPCM_MS },
|
|
{ wxT("asf"), AV_CODEC_ID_PCM_ALAW },
|
|
{ wxT("asf"), AV_CODEC_ID_PCM_MULAW },
|
|
{ wxT("asf"), AV_CODEC_ID_WMAVOICE },
|
|
{ wxT("asf"), AV_CODEC_ID_ADPCM_IMA_WAV },
|
|
{ wxT("asf"), AV_CODEC_ID_ADPCM_YAMAHA },
|
|
{ wxT("asf"), AV_CODEC_ID_TRUESPEECH },
|
|
{ wxT("asf"), AV_CODEC_ID_GSM_MS },
|
|
{ wxT("asf"), AV_CODEC_ID_ADPCM_G726 },
|
|
{ wxT("asf"), AV_CODEC_ID_MP2 },
|
|
{ wxT("asf"), AV_CODEC_ID_MP3 },
|
|
#if LIBAVCODEC_VERSION_MAJOR < 58
|
|
{ wxT("asf"), AV_CODEC_ID_VOXWARE },
|
|
#endif
|
|
{ wxT("asf"), AV_CODEC_ID_AAC },
|
|
{ wxT("asf"), AV_CODEC_ID_WMAV1 },
|
|
{ wxT("asf"), AV_CODEC_ID_WMAV2 },
|
|
{ wxT("asf"), AV_CODEC_ID_WMAPRO },
|
|
{ wxT("asf"), AV_CODEC_ID_ADPCM_CT },
|
|
{ wxT("asf"), AV_CODEC_ID_ATRAC3 },
|
|
{ wxT("asf"), AV_CODEC_ID_IMC },
|
|
{ wxT("asf"), AV_CODEC_ID_AC3 },
|
|
{ wxT("asf"), AV_CODEC_ID_DTS },
|
|
{ wxT("asf"), AV_CODEC_ID_FLAC },
|
|
{ wxT("asf"), AV_CODEC_ID_ADPCM_SWF },
|
|
{ wxT("asf"), AV_CODEC_ID_VORBIS },
|
|
|
|
{ wxT("au"), AV_CODEC_ID_PCM_MULAW },
|
|
{ wxT("au"), AV_CODEC_ID_PCM_S8 },
|
|
{ wxT("au"), AV_CODEC_ID_PCM_S16BE },
|
|
{ wxT("au"), AV_CODEC_ID_PCM_ALAW },
|
|
|
|
{ wxT("avi"), AV_CODEC_ID_PCM_S16LE },
|
|
{ wxT("avi"), AV_CODEC_ID_PCM_U8 },
|
|
{ wxT("avi"), AV_CODEC_ID_PCM_S24LE },
|
|
{ wxT("avi"), AV_CODEC_ID_PCM_S32LE },
|
|
{ wxT("avi"), AV_CODEC_ID_ADPCM_MS },
|
|
{ wxT("avi"), AV_CODEC_ID_PCM_ALAW },
|
|
{ wxT("avi"), AV_CODEC_ID_PCM_MULAW },
|
|
{ wxT("avi"), AV_CODEC_ID_WMAVOICE },
|
|
{ wxT("avi"), AV_CODEC_ID_ADPCM_IMA_WAV },
|
|
{ wxT("avi"), AV_CODEC_ID_ADPCM_YAMAHA },
|
|
{ wxT("avi"), AV_CODEC_ID_TRUESPEECH },
|
|
{ wxT("avi"), AV_CODEC_ID_GSM_MS },
|
|
{ wxT("avi"), AV_CODEC_ID_ADPCM_G726 },
|
|
{ wxT("avi"), AV_CODEC_ID_MP2 },
|
|
{ wxT("avi"), AV_CODEC_ID_MP3 },
|
|
#if LIBAVCODEC_VERSION_MAJOR < 58
|
|
{ wxT("avi"), AV_CODEC_ID_VOXWARE },
|
|
#endif
|
|
{ wxT("avi"), AV_CODEC_ID_AAC },
|
|
{ wxT("avi"), AV_CODEC_ID_WMAV1 },
|
|
{ wxT("avi"), AV_CODEC_ID_WMAV2 },
|
|
{ wxT("avi"), AV_CODEC_ID_WMAPRO },
|
|
{ wxT("avi"), AV_CODEC_ID_ADPCM_CT },
|
|
{ wxT("avi"), AV_CODEC_ID_ATRAC3 },
|
|
{ wxT("avi"), AV_CODEC_ID_IMC },
|
|
{ wxT("avi"), AV_CODEC_ID_AC3 },
|
|
{ wxT("avi"), AV_CODEC_ID_DTS },
|
|
{ wxT("avi"), AV_CODEC_ID_FLAC },
|
|
{ wxT("avi"), AV_CODEC_ID_ADPCM_SWF },
|
|
{ wxT("avi"), AV_CODEC_ID_VORBIS },
|
|
|
|
{ wxT("crc"), AV_CODEC_ID_NONE },
|
|
|
|
{ wxT("dv"), AV_CODEC_ID_PCM_S16LE },
|
|
|
|
{ wxT("ffm"), AV_CODEC_ID_NONE },
|
|
|
|
{ wxT("flv"), AV_CODEC_ID_MP3 },
|
|
{ wxT("flv"), AV_CODEC_ID_PCM_S8 },
|
|
{ wxT("flv"), AV_CODEC_ID_PCM_S16BE },
|
|
{ wxT("flv"), AV_CODEC_ID_PCM_S16LE },
|
|
{ wxT("flv"), AV_CODEC_ID_ADPCM_SWF },
|
|
{ wxT("flv"), AV_CODEC_ID_AAC },
|
|
{ wxT("flv"), AV_CODEC_ID_NELLYMOSER },
|
|
|
|
{ wxT("framecrc"), AV_CODEC_ID_NONE },
|
|
|
|
{ wxT("gxf"), AV_CODEC_ID_PCM_S16LE },
|
|
|
|
{ wxT("matroska"), AV_CODEC_ID_PCM_S16LE },
|
|
{ wxT("matroska"), AV_CODEC_ID_PCM_U8 },
|
|
{ wxT("matroska"), AV_CODEC_ID_PCM_S24LE },
|
|
{ wxT("matroska"), AV_CODEC_ID_PCM_S32LE },
|
|
{ wxT("matroska"), AV_CODEC_ID_ADPCM_MS },
|
|
{ wxT("matroska"), AV_CODEC_ID_PCM_ALAW },
|
|
{ wxT("matroska"), AV_CODEC_ID_PCM_MULAW },
|
|
{ wxT("matroska"), AV_CODEC_ID_WMAVOICE },
|
|
{ wxT("matroska"), AV_CODEC_ID_ADPCM_IMA_WAV },
|
|
{ wxT("matroska"), AV_CODEC_ID_ADPCM_YAMAHA },
|
|
{ wxT("matroska"), AV_CODEC_ID_TRUESPEECH },
|
|
{ wxT("matroska"), AV_CODEC_ID_GSM_MS },
|
|
{ wxT("matroska"), AV_CODEC_ID_ADPCM_G726 },
|
|
{ wxT("matroska"), AV_CODEC_ID_MP2 },
|
|
{ wxT("matroska"), AV_CODEC_ID_MP3 },
|
|
#if LIBAVCODEC_VERSION_MAJOR < 58
|
|
{ wxT("matroska"), AV_CODEC_ID_VOXWARE },
|
|
#endif
|
|
{ wxT("matroska"), AV_CODEC_ID_AAC },
|
|
{ wxT("matroska"), AV_CODEC_ID_WMAV1 },
|
|
{ wxT("matroska"), AV_CODEC_ID_WMAV2 },
|
|
{ wxT("matroska"), AV_CODEC_ID_WMAPRO },
|
|
{ wxT("matroska"), AV_CODEC_ID_ADPCM_CT },
|
|
{ wxT("matroska"), AV_CODEC_ID_ATRAC3 },
|
|
{ wxT("matroska"), AV_CODEC_ID_IMC },
|
|
{ wxT("matroska"), AV_CODEC_ID_AC3 },
|
|
{ wxT("matroska"), AV_CODEC_ID_DTS },
|
|
{ wxT("matroska"), AV_CODEC_ID_FLAC },
|
|
{ wxT("matroska"), AV_CODEC_ID_ADPCM_SWF },
|
|
{ wxT("matroska"), AV_CODEC_ID_VORBIS },
|
|
|
|
{ wxT("mmf"), AV_CODEC_ID_ADPCM_YAMAHA },
|
|
|
|
{ wxT("mov"), AV_CODEC_ID_PCM_S32BE }, //mov
|
|
{ wxT("mov"), AV_CODEC_ID_PCM_S32LE },
|
|
{ wxT("mov"), AV_CODEC_ID_PCM_S24BE },
|
|
{ wxT("mov"), AV_CODEC_ID_PCM_S24LE },
|
|
{ wxT("mov"), AV_CODEC_ID_PCM_S16BE },
|
|
{ wxT("mov"), AV_CODEC_ID_PCM_S16LE },
|
|
{ wxT("mov"), AV_CODEC_ID_PCM_S8 },
|
|
{ wxT("mov"), AV_CODEC_ID_PCM_U8 },
|
|
{ wxT("mov"), AV_CODEC_ID_PCM_MULAW },
|
|
{ wxT("mov"), AV_CODEC_ID_PCM_ALAW },
|
|
{ wxT("mov"), AV_CODEC_ID_ADPCM_IMA_QT },
|
|
{ wxT("mov"), AV_CODEC_ID_MACE3 },
|
|
{ wxT("mov"), AV_CODEC_ID_MACE6 },
|
|
{ wxT("mov"), AV_CODEC_ID_MP3 },
|
|
{ wxT("mov"), AV_CODEC_ID_AAC },
|
|
{ wxT("mov"), AV_CODEC_ID_AMR_NB },
|
|
{ wxT("mov"), AV_CODEC_ID_AMR_WB },
|
|
{ wxT("mov"), AV_CODEC_ID_GSM },
|
|
{ wxT("mov"), AV_CODEC_ID_ALAC },
|
|
{ wxT("mov"), AV_CODEC_ID_QCELP },
|
|
{ wxT("mov"), AV_CODEC_ID_QDM2 },
|
|
{ wxT("mov"), AV_CODEC_ID_DVAUDIO },
|
|
{ wxT("mov"), AV_CODEC_ID_WMAV2 },
|
|
{ wxT("mov"), AV_CODEC_ID_ALAC },
|
|
|
|
{ wxT("mp4"), AV_CODEC_ID_AAC },
|
|
{ wxT("mp4"), AV_CODEC_ID_QCELP },
|
|
{ wxT("mp4"), AV_CODEC_ID_MP3 },
|
|
{ wxT("mp4"), AV_CODEC_ID_VORBIS },
|
|
|
|
{ wxT("psp"), AV_CODEC_ID_AAC },
|
|
{ wxT("psp"), AV_CODEC_ID_QCELP },
|
|
{ wxT("psp"), AV_CODEC_ID_MP3 },
|
|
{ wxT("psp"), AV_CODEC_ID_VORBIS },
|
|
|
|
{ wxT("ipod"), AV_CODEC_ID_AAC },
|
|
{ wxT("ipod"), AV_CODEC_ID_QCELP },
|
|
{ wxT("ipod"), AV_CODEC_ID_MP3 },
|
|
{ wxT("ipod"), AV_CODEC_ID_VORBIS },
|
|
|
|
{ wxT("3gp"), AV_CODEC_ID_AAC },
|
|
{ wxT("3gp"), AV_CODEC_ID_AMR_NB },
|
|
{ wxT("3gp"), AV_CODEC_ID_AMR_WB },
|
|
|
|
{ wxT("3g2"), AV_CODEC_ID_AAC },
|
|
{ wxT("3g2"), AV_CODEC_ID_AMR_NB },
|
|
{ wxT("3g2"), AV_CODEC_ID_AMR_WB },
|
|
|
|
{ wxT("mp3"), AV_CODEC_ID_MP3 },
|
|
|
|
{ wxT("mpeg"), AV_CODEC_ID_AC3 },
|
|
{ wxT("mpeg"), AV_CODEC_ID_DTS },
|
|
{ wxT("mpeg"), AV_CODEC_ID_PCM_S16BE },
|
|
{ wxT("mpeg"), AV_CODEC_ID_MP2 },
|
|
|
|
{ wxT("vcd"), AV_CODEC_ID_AC3 },
|
|
{ wxT("vcd"), AV_CODEC_ID_DTS },
|
|
{ wxT("vcd"), AV_CODEC_ID_PCM_S16BE },
|
|
{ wxT("vcd"), AV_CODEC_ID_MP2 },
|
|
|
|
{ wxT("vob"), AV_CODEC_ID_AC3 },
|
|
{ wxT("vob"), AV_CODEC_ID_DTS },
|
|
{ wxT("vob"), AV_CODEC_ID_PCM_S16BE },
|
|
{ wxT("vob"), AV_CODEC_ID_MP2 },
|
|
|
|
{ wxT("svcd"), AV_CODEC_ID_AC3 },
|
|
{ wxT("svcd"), AV_CODEC_ID_DTS },
|
|
{ wxT("svcd"), AV_CODEC_ID_PCM_S16BE },
|
|
{ wxT("svcd"), AV_CODEC_ID_MP2 },
|
|
|
|
{ wxT("dvd"), AV_CODEC_ID_AC3 },
|
|
{ wxT("dvd"), AV_CODEC_ID_DTS },
|
|
{ wxT("dvd"), AV_CODEC_ID_PCM_S16BE },
|
|
{ wxT("dvd"), AV_CODEC_ID_MP2 },
|
|
|
|
{ wxT("nut"), AV_CODEC_ID_PCM_S16LE },
|
|
{ wxT("nut"), AV_CODEC_ID_PCM_U8 },
|
|
{ wxT("nut"), AV_CODEC_ID_PCM_S24LE },
|
|
{ wxT("nut"), AV_CODEC_ID_PCM_S32LE },
|
|
{ wxT("nut"), AV_CODEC_ID_ADPCM_MS },
|
|
{ wxT("nut"), AV_CODEC_ID_PCM_ALAW },
|
|
{ wxT("nut"), AV_CODEC_ID_PCM_MULAW },
|
|
{ wxT("nut"), AV_CODEC_ID_WMAVOICE },
|
|
{ wxT("nut"), AV_CODEC_ID_ADPCM_IMA_WAV },
|
|
{ wxT("nut"), AV_CODEC_ID_ADPCM_YAMAHA },
|
|
{ wxT("nut"), AV_CODEC_ID_TRUESPEECH },
|
|
{ wxT("nut"), AV_CODEC_ID_GSM_MS },
|
|
{ wxT("nut"), AV_CODEC_ID_ADPCM_G726 },
|
|
{ wxT("nut"), AV_CODEC_ID_MP2 },
|
|
{ wxT("nut"), AV_CODEC_ID_MP3 },
|
|
#if LIBAVCODEC_VERSION_MAJOR < 58
|
|
{ wxT("nut"), AV_CODEC_ID_VOXWARE },
|
|
#endif
|
|
{ wxT("nut"), AV_CODEC_ID_AAC },
|
|
{ wxT("nut"), AV_CODEC_ID_WMAV1 },
|
|
{ wxT("nut"), AV_CODEC_ID_WMAV2 },
|
|
{ wxT("nut"), AV_CODEC_ID_WMAPRO },
|
|
{ wxT("nut"), AV_CODEC_ID_ADPCM_CT },
|
|
{ wxT("nut"), AV_CODEC_ID_ATRAC3 },
|
|
{ wxT("nut"), AV_CODEC_ID_IMC },
|
|
{ wxT("nut"), AV_CODEC_ID_AC3 },
|
|
{ wxT("nut"), AV_CODEC_ID_DTS },
|
|
{ wxT("nut"), AV_CODEC_ID_FLAC },
|
|
{ wxT("nut"), AV_CODEC_ID_ADPCM_SWF },
|
|
{ wxT("nut"), AV_CODEC_ID_VORBIS },
|
|
|
|
{ wxT("ogg"), AV_CODEC_ID_VORBIS },
|
|
{ wxT("ogg"), AV_CODEC_ID_FLAC },
|
|
|
|
{ wxT("ac3"), AV_CODEC_ID_AC3 },
|
|
|
|
{ wxT("dts"), AV_CODEC_ID_DTS },
|
|
|
|
{ wxT("flac"), AV_CODEC_ID_FLAC },
|
|
|
|
{ wxT("RoQ"), AV_CODEC_ID_ROQ_DPCM },
|
|
|
|
{ wxT("rm"), AV_CODEC_ID_AC3 },
|
|
|
|
{ wxT("swf"), AV_CODEC_ID_MP3 },
|
|
|
|
{ wxT("avm2"), AV_CODEC_ID_MP3 },
|
|
|
|
{ wxT("voc"), AV_CODEC_ID_PCM_U8 },
|
|
|
|
{ wxT("wav"), AV_CODEC_ID_PCM_S16LE },
|
|
{ wxT("wav"), AV_CODEC_ID_PCM_U8 },
|
|
{ wxT("wav"), AV_CODEC_ID_PCM_S24LE },
|
|
{ wxT("wav"), AV_CODEC_ID_PCM_S32LE },
|
|
{ wxT("wav"), AV_CODEC_ID_ADPCM_MS },
|
|
{ wxT("wav"), AV_CODEC_ID_PCM_ALAW },
|
|
{ wxT("wav"), AV_CODEC_ID_PCM_MULAW },
|
|
{ wxT("wav"), AV_CODEC_ID_WMAVOICE },
|
|
{ wxT("wav"), AV_CODEC_ID_ADPCM_IMA_WAV },
|
|
{ wxT("wav"), AV_CODEC_ID_ADPCM_YAMAHA },
|
|
{ wxT("wav"), AV_CODEC_ID_TRUESPEECH },
|
|
{ wxT("wav"), AV_CODEC_ID_GSM_MS },
|
|
{ wxT("wav"), AV_CODEC_ID_ADPCM_G726 },
|
|
{ wxT("wav"), AV_CODEC_ID_MP2 },
|
|
{ wxT("wav"), AV_CODEC_ID_MP3 },
|
|
#if LIBAVCODEC_VERSION_MAJOR < 58
|
|
{ wxT("wav"), AV_CODEC_ID_VOXWARE },
|
|
#endif
|
|
{ wxT("wav"), AV_CODEC_ID_AAC },
|
|
{ wxT("wav"), AV_CODEC_ID_WMAV1 },
|
|
{ wxT("wav"), AV_CODEC_ID_WMAV2 },
|
|
{ wxT("wav"), AV_CODEC_ID_WMAPRO },
|
|
{ wxT("wav"), AV_CODEC_ID_ADPCM_CT },
|
|
{ wxT("wav"), AV_CODEC_ID_ATRAC3 },
|
|
{ wxT("wav"), AV_CODEC_ID_IMC },
|
|
{ wxT("wav"), AV_CODEC_ID_AC3 },
|
|
{ wxT("wav"), AV_CODEC_ID_DTS },
|
|
{ wxT("wav"), AV_CODEC_ID_FLAC },
|
|
{ wxT("wav"), AV_CODEC_ID_ADPCM_SWF },
|
|
{ wxT("wav"), AV_CODEC_ID_VORBIS },
|
|
|
|
{ NULL, AV_CODEC_ID_NONE }
|
|
};
|
|
|
|
/// AAC profiles
|
|
int ExportFFmpegOptions::iAACProfileValues[] = {
|
|
FF_PROFILE_AAC_LOW,
|
|
FF_PROFILE_AAC_MAIN,
|
|
/*FF_PROFILE_AAC_SSR,*/
|
|
FF_PROFILE_AAC_LTP
|
|
};
|
|
|
|
/// Names of AAC profiles to be displayed
|
|
static wxString iAACProfileNames(int index)
|
|
{
|
|
static const wxString names[] = {
|
|
XO("LC"),
|
|
XO("Main"),
|
|
/*_("SSR"),*/ //SSR is not supported
|
|
XO("LTP")
|
|
};
|
|
|
|
class NamesArray final : public TranslatableStringArray
|
|
{
|
|
void Populate() override
|
|
{
|
|
for (auto &name : names)
|
|
mContents.push_back( wxGetTranslation( name ) );
|
|
}
|
|
};
|
|
|
|
static NamesArray theArray;
|
|
|
|
return theArray.Get()[ index ];
|
|
}
|
|
|
|
/// List of export types
|
|
ExposedFormat ExportFFmpegOptions::fmts[] =
|
|
{
|
|
{FMT_M4A, wxT("M4A"), wxT("m4a"), wxT("ipod"), 48, AV_CANMETA, true, XO("M4A (AAC) Files (FFmpeg)"), AV_CODEC_ID_AAC, true},
|
|
{FMT_AC3, wxT("AC3"), wxT("ac3"), wxT("ac3"), 7, AV_VERSION_INT(0,0,0), false, XO("AC3 Files (FFmpeg)"), AV_CODEC_ID_AC3, true},
|
|
{FMT_AMRNB, wxT("AMRNB"), wxT("amr"), wxT("amr"), 1, AV_VERSION_INT(0,0,0), false, XO("AMR (narrow band) Files (FFmpeg)"), AV_CODEC_ID_AMR_NB, true},
|
|
{FMT_WMA2, wxT("WMA"), wxT("wma"), wxT("asf"), 2, AV_VERSION_INT(52,53,0), false, XO("WMA (version 2) Files (FFmpeg)"), AV_CODEC_ID_WMAV2, true},
|
|
{FMT_OTHER, wxT("FFMPEG"), wxT(""), wxT(""), 255, AV_CANMETA, true, XO("Custom FFmpeg Export"), AV_CODEC_ID_NONE, true}
|
|
};
|
|
|
|
wxString ExposedFormat::Description() const
|
|
{
|
|
return wxGetTranslation(description_);
|
|
}
|
|
|
|
/// Sample rates supported by AAC encoder (must end with zero-element)
|
|
const int ExportFFmpegOptions::iAACSampleRates[] = { 7350, 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000, 64000, 88200, 0 };
|
|
|
|
/// Some controls (parameters they represent) are only applicable to a number
|
|
/// of codecs and/or formats.
|
|
/// Syntax: first, enable a control for each applicable format-codec combination
|
|
/// then disable it for anything else
|
|
/// "any" - any format
|
|
/// AV_CODEC_ID_NONE - any codec
|
|
/// This list must end with {FALSE,FFmpegExportCtrlID(0),AV_CODEC_ID_NONE,NULL}
|
|
ApplicableFor ExportFFmpegOptions::apptable[] =
|
|
{
|
|
{TRUE,FEQualityID,AV_CODEC_ID_AAC,"any"},
|
|
{TRUE,FEQualityID,AV_CODEC_ID_MP3,"any"},
|
|
{TRUE,FEQualityID,AV_CODEC_ID_VORBIS,"any"},
|
|
{FALSE,FEQualityID,AV_CODEC_ID_NONE,"any"},
|
|
|
|
{TRUE,FECutoffID,AV_CODEC_ID_AC3,"any"},
|
|
{TRUE,FECutoffID,AV_CODEC_ID_AAC,"any"},
|
|
{TRUE,FECutoffID,AV_CODEC_ID_VORBIS,"any"},
|
|
{FALSE,FECutoffID,AV_CODEC_ID_NONE,"any"},
|
|
|
|
{TRUE,FEFrameSizeID,AV_CODEC_ID_FLAC,"any"},
|
|
{FALSE,FEFrameSizeID,AV_CODEC_ID_NONE,"any"},
|
|
|
|
{TRUE,FEProfileID,AV_CODEC_ID_AAC,"any"},
|
|
{FALSE,FEProfileID,AV_CODEC_ID_NONE,"any"},
|
|
|
|
{TRUE,FECompLevelID,AV_CODEC_ID_FLAC,"any"},
|
|
{FALSE,FECompLevelID,AV_CODEC_ID_NONE,"any"},
|
|
|
|
{TRUE,FEUseLPCID,AV_CODEC_ID_FLAC,"any"},
|
|
{FALSE,FEUseLPCID,AV_CODEC_ID_NONE,"any"},
|
|
|
|
{TRUE,FELPCCoeffsID,AV_CODEC_ID_FLAC,"any"},
|
|
{FALSE,FELPCCoeffsID,AV_CODEC_ID_NONE,"any"},
|
|
|
|
{TRUE,FEMinPredID,AV_CODEC_ID_FLAC,"any"},
|
|
{FALSE,FEMinPredID,AV_CODEC_ID_NONE,"any"},
|
|
|
|
{TRUE,FEMaxPredID,AV_CODEC_ID_FLAC,"any"},
|
|
{FALSE,FEMaxPredID,AV_CODEC_ID_NONE,"any"},
|
|
|
|
{TRUE,FEPredOrderID,AV_CODEC_ID_FLAC,"any"},
|
|
{FALSE,FEPredOrderID,AV_CODEC_ID_NONE,"any"},
|
|
|
|
{TRUE,FEMinPartOrderID,AV_CODEC_ID_FLAC,"any"},
|
|
{FALSE,FEMinPartOrderID,AV_CODEC_ID_NONE,"any"},
|
|
|
|
{TRUE,FEMaxPartOrderID,AV_CODEC_ID_FLAC,"any"},
|
|
{FALSE,FEMaxPartOrderID,AV_CODEC_ID_NONE,"any"},
|
|
|
|
{TRUE,FEMuxRateID,AV_CODEC_ID_NONE,"mpeg"},
|
|
{TRUE,FEMuxRateID,AV_CODEC_ID_NONE,"vcd"},
|
|
{TRUE,FEMuxRateID,AV_CODEC_ID_NONE,"vob"},
|
|
{TRUE,FEMuxRateID,AV_CODEC_ID_NONE,"svcd"},
|
|
{TRUE,FEMuxRateID,AV_CODEC_ID_NONE,"dvd"},
|
|
{FALSE,FEMuxRateID,AV_CODEC_ID_NONE,"any"},
|
|
|
|
{TRUE,FEPacketSizeID,AV_CODEC_ID_NONE,"mpeg"},
|
|
{TRUE,FEPacketSizeID,AV_CODEC_ID_NONE,"vcd"},
|
|
{TRUE,FEPacketSizeID,AV_CODEC_ID_NONE,"vob"},
|
|
{TRUE,FEPacketSizeID,AV_CODEC_ID_NONE,"svcd"},
|
|
{TRUE,FEPacketSizeID,AV_CODEC_ID_NONE,"dvd"},
|
|
{FALSE,FEPacketSizeID,AV_CODEC_ID_NONE,"any"},
|
|
|
|
{TRUE,FELanguageID,AV_CODEC_ID_NONE,"matroska"},
|
|
{TRUE,FELanguageID,AV_CODEC_ID_NONE,"mov"},
|
|
{TRUE,FELanguageID,AV_CODEC_ID_NONE,"3gp"},
|
|
{TRUE,FELanguageID,AV_CODEC_ID_NONE,"mp4"},
|
|
{TRUE,FELanguageID,AV_CODEC_ID_NONE,"psp"},
|
|
{TRUE,FELanguageID,AV_CODEC_ID_NONE,"3g2"},
|
|
{TRUE,FELanguageID,AV_CODEC_ID_NONE,"ipod"},
|
|
{TRUE,FELanguageID,AV_CODEC_ID_NONE,"mpegts"},
|
|
{FALSE,FELanguageID,AV_CODEC_ID_NONE,"any"},
|
|
|
|
{TRUE,FEBitReservoirID,AV_CODEC_ID_MP3,"any"},
|
|
{TRUE,FEBitReservoirID,AV_CODEC_ID_WMAV1,"any"},
|
|
{TRUE,FEBitReservoirID,AV_CODEC_ID_WMAV2,"any"},
|
|
{FALSE,FEBitReservoirID,AV_CODEC_ID_NONE,"any"},
|
|
|
|
{TRUE,FEVariableBlockLenID,AV_CODEC_ID_WMAV1,"any"},
|
|
{TRUE,FEVariableBlockLenID,AV_CODEC_ID_WMAV2,"any"},
|
|
{FALSE,FEVariableBlockLenID,AV_CODEC_ID_NONE,"any"},
|
|
|
|
{FALSE,FFmpegExportCtrlID(0),AV_CODEC_ID_NONE,NULL}
|
|
};
|
|
|
|
/// Prediction order method - names. Labels are indices of this array.
|
|
static wxString PredictionOrderMethodNames(int index)
|
|
{
|
|
static const wxString names[] = {
|
|
XO("Estimate"),
|
|
XO("2-level"),
|
|
XO("4-level"),
|
|
XO("8-level"),
|
|
XO("Full search"),
|
|
XO("Log search")
|
|
};
|
|
|
|
class NamesArray final : public TranslatableStringArray
|
|
{
|
|
void Populate() override
|
|
{
|
|
for (auto &name : names)
|
|
mContents.push_back( wxGetTranslation( name ) );
|
|
}
|
|
};
|
|
|
|
static NamesArray theArray;
|
|
|
|
return theArray.Get()[ index ];
|
|
}
|
|
|
|
|
|
|
|
ExportFFmpegOptions::~ExportFFmpegOptions()
|
|
{
|
|
DropFFmpegLibs();
|
|
}
|
|
|
|
ExportFFmpegOptions::ExportFFmpegOptions(wxWindow *parent)
|
|
: wxDialogWrapper(parent, wxID_ANY,
|
|
wxString(_("Configure custom FFmpeg options")))
|
|
{
|
|
SetName(GetTitle());
|
|
ShuttleGui S(this, eIsCreatingFromPrefs);
|
|
PickFFmpegLibs();
|
|
//FFmpegLibsInst()->LoadLibs(NULL,true); //Loaded at startup or from Prefs now
|
|
|
|
mPresets = std::make_unique<FFmpegPresets>();
|
|
mPresets->GetPresetList(mPresetNames);
|
|
|
|
if (FFmpegLibsInst()->ValidLibsLoaded())
|
|
{
|
|
FetchFormatList();
|
|
FetchCodecList();
|
|
|
|
for (unsigned int i = 0; i < 6; i++)
|
|
{
|
|
mPredictionOrderMethodLabels.push_back(i);
|
|
mPredictionOrderMethodNames.push_back(wxString::Format(wxT("%s"),PredictionOrderMethodNames(i)));
|
|
}
|
|
|
|
for (unsigned int i=0; i < (sizeof(iAACProfileValues)/sizeof(int)); i++)
|
|
{
|
|
mProfileNames.push_back(wxString::Format(wxT("%s"),iAACProfileNames(i)));
|
|
mProfileLabels.push_back(iAACProfileValues[i]);
|
|
}
|
|
|
|
PopulateOrExchange(S);
|
|
|
|
//Select the format that was selected last time this dialog was closed
|
|
mFormatList->Select(mFormatList->FindString(gPrefs->Read(wxT("/FileFormats/FFmpegFormat"))));
|
|
DoOnFormatList();
|
|
|
|
//Select the codec that was selected last time this dialog was closed
|
|
AVCodec *codec = avcodec_find_encoder_by_name(gPrefs->Read(wxT("/FileFormats/FFmpegCodec")).ToUTF8());
|
|
if (codec != NULL) mCodecList->Select(mCodecList->FindString(wxString::FromUTF8(codec->name)));
|
|
DoOnCodecList();
|
|
}
|
|
|
|
}
|
|
|
|
///
|
|
///
|
|
void ExportFFmpegOptions::FetchFormatList()
|
|
{
|
|
// Enumerate all output formats
|
|
AVOutputFormat *ofmt = NULL;
|
|
while ((ofmt = av_oformat_next(ofmt))!=NULL)
|
|
{
|
|
// Any audio-capable format has default audio codec.
|
|
// If it doesn't, then it doesn't supports any audio codecs
|
|
if (ofmt->audio_codec != AV_CODEC_ID_NONE)
|
|
{
|
|
mFormatNames.push_back(wxString::FromUTF8(ofmt->name));
|
|
mFormatLongNames.push_back(wxString::Format(wxT("%s - %s"),mFormatNames.back(),wxString::FromUTF8(ofmt->long_name)));
|
|
}
|
|
}
|
|
// Show all formats
|
|
mShownFormatNames = mFormatNames;
|
|
mShownFormatLongNames = mFormatLongNames;
|
|
}
|
|
|
|
///
|
|
///
|
|
void ExportFFmpegOptions::FetchCodecList()
|
|
{
|
|
// Enumerate all codecs
|
|
AVCodec *codec = NULL;
|
|
while ((codec = av_codec_next(codec))!=NULL)
|
|
{
|
|
// We're only interested in audio and only in encoders
|
|
if (codec->type == AVMEDIA_TYPE_AUDIO && av_codec_is_encoder(codec))
|
|
{
|
|
mCodecNames.push_back(wxString::FromUTF8(codec->name));
|
|
mCodecLongNames.push_back(wxString::Format(wxT("%s - %s"),mCodecNames.back(),wxString::FromUTF8(codec->long_name)));
|
|
}
|
|
}
|
|
// Show all codecs
|
|
mShownCodecNames = mCodecNames;
|
|
mShownCodecLongNames = mCodecLongNames;
|
|
}
|
|
|
|
///
|
|
///
|
|
void ExportFFmpegOptions::PopulateOrExchange(ShuttleGui & S)
|
|
{
|
|
S.StartVerticalLay(1);
|
|
S.StartMultiColumn(1, wxEXPAND);
|
|
{
|
|
S.SetStretchyRow(3);
|
|
S.StartMultiColumn(7, wxEXPAND);
|
|
{
|
|
S.SetStretchyCol(1);
|
|
mPresetCombo = S.Id(FEPresetID).AddCombo(_("Preset:"), gPrefs->Read(wxT("/FileFormats/FFmpegPreset"),wxEmptyString), mPresetNames);
|
|
mLoadPreset = S.Id(FELoadPresetID).AddButton(_("Load Preset"));
|
|
mSavePreset = S.Id(FESavePresetID).AddButton(_("Save Preset"));
|
|
mDeletePreset = S.Id(FEDeletePresetID).AddButton(_("Delete Preset"));
|
|
mImportPresets = S.Id(FEImportPresetsID).AddButton(_("Import Presets"));
|
|
mExportPresets = S.Id(FEExportPresetsID).AddButton(_("Export Presets"));
|
|
}
|
|
S.EndMultiColumn();
|
|
S.StartMultiColumn(4, wxALIGN_LEFT);
|
|
{
|
|
S.SetStretchyCol(1);
|
|
S.SetStretchyCol(3);
|
|
S.Id(FEFormatLabelID).AddFixedText(_("Format:"));
|
|
mFormatName = S.Id(FEFormatNameID).AddVariableText( {} );
|
|
S.Id(FECodecLabelID).AddFixedText(_("Codec:"));
|
|
mCodecName = S.Id(FECodecNameID).AddVariableText( {} );
|
|
}
|
|
S.EndMultiColumn();
|
|
S.AddVariableText(_("Not all formats and codecs are compatible. Nor are all option combinations compatible with all codecs."), false);
|
|
S.StartMultiColumn(2, wxEXPAND);
|
|
{
|
|
S.StartMultiColumn(2, wxEXPAND);
|
|
{
|
|
S.SetStretchyRow(1);
|
|
S.Id(FEAllFormatsID).AddButton(_("Show All Formats"));
|
|
S.Id(FEAllCodecsID).AddButton(_("Show All Codecs"));
|
|
mFormatList = S.Id(FEFormatID).AddListBox(mFormatNames);
|
|
mFormatList->DeselectAll();
|
|
mCodecList = S.Id(FECodecID).AddListBox(mCodecNames);
|
|
mCodecList->DeselectAll();
|
|
}
|
|
S.EndMultiColumn();
|
|
S.StartVerticalLay();
|
|
{
|
|
//S.StartScroller( );
|
|
S.SetBorder( 3 );
|
|
S.StartStatic(_("General Options"), 0);
|
|
{
|
|
S.StartMultiColumn(8, wxEXPAND);
|
|
{
|
|
mLanguageText = S.Id(FELanguageID).TieTextBox(_("Language:"), wxT("/FileFormats/FFmpegLanguage"), wxEmptyString, 9);
|
|
mLanguageText->SetToolTip(_("ISO 639 3-letter language code\nOptional\nempty - automatic"));
|
|
|
|
S.AddSpace( 20,0 );
|
|
S.AddVariableText(_("Bit Reservoir"));
|
|
S.Id(FEBitReservoirID).TieCheckBox( {}, wxT("/FileFormats/FFmpegBitReservoir"), true);
|
|
|
|
S.AddSpace( 20,0 );
|
|
S.AddVariableText(_("VBL"));
|
|
S.Id(FEVariableBlockLenID).TieCheckBox( {}, wxT("/FileFormats/FFmpegVariableBlockLen"), true);
|
|
}
|
|
S.EndMultiColumn();
|
|
S.StartMultiColumn(4, wxALIGN_LEFT);
|
|
{
|
|
mTag = S.Id(FETagID).TieTextBox(_("Tag:"), wxT("/FileFormats/FFmpegTag"), wxEmptyString, 4);
|
|
mTag->SetToolTip(_("Codec tag (FOURCC)\nOptional\nempty - automatic"));
|
|
|
|
mBitrateSpin = S.Id(FEBitrateID).TieSpinCtrl(_("Bit Rate:"), wxT("/FileFormats/FFmpegBitRate"), 0, 1000000, 0);
|
|
mBitrateSpin->SetToolTip(_("Bit Rate (bits/second) - influences the resulting file size and quality\nSome codecs may only accept specific values (128k, 192k, 256k etc)\n0 - automatic\nRecommended - 192000"));
|
|
|
|
mQualitySpin = S.Id(FEQualityID).TieSpinCtrl(_("Quality:"), wxT("/FileFormats/FFmpegQuality"), 0, 500, -1);
|
|
mQualitySpin->SetToolTip(_("Overall quality, used differently by different codecs\nRequired for vorbis\n0 - automatic\n-1 - off (use bitrate instead)"));
|
|
|
|
mSampleRateSpin = S.Id(FESampleRateID).TieSpinCtrl(_("Sample Rate:"), wxT("/FileFormats/FFmpegSampleRate"), 0, 200000, 0);
|
|
mSampleRateSpin->SetToolTip(_("Sample rate (Hz)\n0 - don't change sample rate"));
|
|
|
|
mCutoffSpin = S.Id(FECutoffID).TieSpinCtrl(_("Cutoff:"), wxT("/FileFormats/FFmpegCutOff"), 0, 10000000, 0);
|
|
mCutoffSpin->SetToolTip(_("Audio cutoff bandwidth (Hz)\nOptional\n0 - automatic"));
|
|
|
|
mProfileChoice = S.Id(FEProfileID).TieChoice(_("Profile:"), wxT("/FileFormats/FFmpegAACProfile"),
|
|
mProfileLabels[0], mProfileNames, mProfileLabels);
|
|
mProfileChoice->SetSizeHints( 100,-1);
|
|
mProfileChoice->SetToolTip(_("AAC Profile\nLow Complexity - default\nMost players won't play anything other than LC"));
|
|
|
|
}
|
|
S.EndMultiColumn();
|
|
}
|
|
S.EndStatic();
|
|
S.StartStatic(_("FLAC options"),0);
|
|
{
|
|
S.StartMultiColumn(4, wxALIGN_LEFT);
|
|
{
|
|
mCompressionLevelSpin = S.Id(FECompLevelID).TieSpinCtrl(_("Compression:"), wxT("/FileFormats/FFmpegCompLevel"), 0, 10, -1);
|
|
mCompressionLevelSpin->SetToolTip(_("Compression level\nRequired for FLAC\n-1 - automatic\nmin - 0 (fast encoding, large output file)\nmax - 10 (slow encoding, small output file)"));
|
|
|
|
mFrameSizeSpin = S.Id(FEFrameSizeID).TieSpinCtrl(_("Frame:"), wxT("/FileFormats/FFmpegFrameSize"), 0, 65535, 0);
|
|
mFrameSizeSpin->SetToolTip(_("Frame size\nOptional\n0 - default\nmin - 16\nmax - 65535"));
|
|
|
|
mLPCCoeffsPrecisionSpin = S.Id(FELPCCoeffsID).TieSpinCtrl(_("LPC"), wxT("/FileFormats/FFmpegLPCCoefPrec"), 0, 15, 0);
|
|
mLPCCoeffsPrecisionSpin->SetToolTip(_("LPC coefficients precision\nOptional\n0 - default\nmin - 1\nmax - 15"));
|
|
|
|
mPredictionOrderMethodChoice = S.Id(FEPredOrderID).TieChoice(_("PdO Method:"), wxT("/FileFormats/FFmpegPredOrderMethod"),
|
|
mPredictionOrderMethodLabels[4], mPredictionOrderMethodNames, mPredictionOrderMethodLabels);
|
|
mPredictionOrderMethodChoice->SetSizeHints( 100,-1);
|
|
mPredictionOrderMethodChoice->SetToolTip(_("Prediction Order Method\nEstimate - fastest, lower compression\nLog search - slowest, best compression\nFull search - default"));
|
|
|
|
mMinPredictionOrderSpin = S.Id(FEMinPredID).TieSpinCtrl(_("Min. PdO"), wxT("/FileFormats/FFmpegMinPredOrder"), -1, 32, -1);
|
|
mMinPredictionOrderSpin->SetToolTip(_("Minimal prediction order\nOptional\n-1 - default\nmin - 0\nmax - 32 (with LPC) or 4 (without LPC)"));
|
|
|
|
mMaxPredictionOrderSpin = S.Id(FEMaxPredID).TieSpinCtrl(_("Max. PdO"), wxT("/FileFormats/FFmpegMaxPredOrder"), -1, 32, -1);
|
|
mMaxPredictionOrderSpin->SetToolTip(_("Maximal prediction order\nOptional\n-1 - default\nmin - 0\nmax - 32 (with LPC) or 4 (without LPC)"));
|
|
|
|
mMinPartitionOrderSpin = S.Id(FEMinPartOrderID).TieSpinCtrl(_("Min. PtO"), wxT("/FileFormats/FFmpegMinPartOrder"), -1, 8, -1);
|
|
mMinPartitionOrderSpin->SetToolTip(_("Minimal partition order\nOptional\n-1 - default\nmin - 0\nmax - 8"));
|
|
|
|
mMaxPartitionOrderSpin = S.Id(FEMaxPartOrderID).TieSpinCtrl(_("Max. PtO"), wxT("/FileFormats/FFmpegMaxPartOrder"), -1, 8, -1);
|
|
mMaxPartitionOrderSpin->SetToolTip(_("Maximal partition order\nOptional\n-1 - default\nmin - 0\nmax - 8"));
|
|
|
|
/* i18n-hint: Abbreviates "Linear Predictive Coding",
|
|
but this text needs to be kept very short */
|
|
S.AddVariableText(_("Use LPC"));
|
|
// PRL: This preference is not used anywhere!
|
|
S.Id(FEUseLPCID).TieCheckBox( {}, wxT("/FileFormats/FFmpegUseLPC"), true);
|
|
}
|
|
S.EndMultiColumn();
|
|
}
|
|
S.EndStatic();
|
|
S.StartStatic(_("MPEG container options"),0);
|
|
{
|
|
S.StartMultiColumn(4, wxALIGN_LEFT);
|
|
{
|
|
/* i18n-hint: 'mux' is short for multiplexor, a device that selects between several inputs
|
|
'Mux Rate' is a parameter that has some bearing on compression ratio for MPEG
|
|
it has a hard to predict effect on the degree of compression */
|
|
mMuxRate = S.Id(FEMuxRateID).TieSpinCtrl(_("Mux Rate:"), wxT("/FileFormats/FFmpegMuxRate"), 0, 10000000, 0);
|
|
mMuxRate->SetToolTip(_("Maximum bit rate of the multiplexed stream\nOptional\n0 - default"));
|
|
|
|
/* i18n-hint: 'Packet Size' is a parameter that has some bearing on compression ratio for MPEG
|
|
compression. It measures how big a chunk of audio is compressed in one piece. */
|
|
mPacketSize = S.Id(FEPacketSizeID).TieSpinCtrl(_("Packet Size:"), wxT("/FileFormats/FFmpegPacketSize"), 0, 10000000, 0);
|
|
mPacketSize->SetToolTip(_("Packet size\nOptional\n0 - default"));
|
|
}
|
|
S.EndMultiColumn();
|
|
}
|
|
S.EndStatic();
|
|
//S.EndScroller();
|
|
S.SetBorder( 5 );
|
|
S.AddStandardButtons();
|
|
}
|
|
S.EndVerticalLay();
|
|
}
|
|
S.EndMultiColumn();
|
|
}
|
|
S.EndMultiColumn();
|
|
S.EndVerticalLay();
|
|
|
|
Layout();
|
|
Fit();
|
|
SetMinSize(GetSize());
|
|
Center();
|
|
|
|
return;
|
|
}
|
|
|
|
///
|
|
///
|
|
void ExportFFmpegOptions::FindSelectedFormat(wxString **name, wxString **longname)
|
|
{
|
|
// Get current selection
|
|
wxArrayInt selections;
|
|
int n = mFormatList->GetSelections(selections);
|
|
if (n <= 0) return;
|
|
|
|
// Get selected format short name
|
|
wxString selfmt = mFormatList->GetString(selections[0]);
|
|
|
|
// Find it's index
|
|
int nFormat = make_iterator_range( mFormatNames ).index( selfmt );
|
|
if (nFormat == wxNOT_FOUND) return;
|
|
|
|
// Return short name and description
|
|
if (name != NULL) *name = &mFormatNames[nFormat];
|
|
if (longname != NULL) *longname = &mFormatLongNames[nFormat];
|
|
return;
|
|
}
|
|
///
|
|
///
|
|
void ExportFFmpegOptions::FindSelectedCodec(wxString **name, wxString **longname)
|
|
{
|
|
// Get current selection
|
|
wxArrayInt selections;
|
|
int n = mCodecList->GetSelections(selections);
|
|
if (n <= 0) return;
|
|
|
|
// Get selected codec short name
|
|
wxString selcdc = mCodecList->GetString(selections[0]);
|
|
|
|
// Find it's index
|
|
int nCodec = make_iterator_range( mCodecNames ).index( selcdc );
|
|
if (nCodec == wxNOT_FOUND) return;
|
|
|
|
// Return short name and description
|
|
if (name != NULL) *name = &mCodecNames[nCodec];
|
|
if (longname != NULL) *longname = &mCodecLongNames[nCodec];
|
|
}
|
|
|
|
///
|
|
///
|
|
int ExportFFmpegOptions::FetchCompatibleCodecList(const wxChar *fmt, AVCodecID id)
|
|
{
|
|
// By default assume that id is not in the list
|
|
int index = -1;
|
|
// By default no codecs are compatible (yet)
|
|
mShownCodecNames.clear();
|
|
mShownCodecLongNames.clear();
|
|
// Clear the listbox
|
|
mCodecList->Clear();
|
|
// Zero - format is not found at all
|
|
int found = 0;
|
|
wxString str(fmt);
|
|
for (int i = 0; CompatibilityList[i].fmt != NULL; i++)
|
|
{
|
|
if (str == CompatibilityList[i].fmt)
|
|
{
|
|
// Format is found in the list
|
|
found = 1;
|
|
if (CompatibilityList[i].codec == AV_CODEC_ID_NONE)
|
|
{
|
|
// Format is found in the list and it is compatible with AV_CODEC_ID_NONE (means that it is compatible to anything)
|
|
found = 2;
|
|
break;
|
|
}
|
|
// Find the codec, that is claimed to be compatible
|
|
AVCodec *codec = avcodec_find_encoder(CompatibilityList[i].codec);
|
|
// If it exists, is audio and has encoder
|
|
if (codec != NULL && (codec->type == AVMEDIA_TYPE_AUDIO) && av_codec_is_encoder(codec))
|
|
{
|
|
// If it was selected - remember it's NEW index
|
|
if ((id >= 0) && codec->id == id) index = mShownCodecNames.size();
|
|
mShownCodecNames.push_back(wxString::FromUTF8(codec->name));
|
|
mShownCodecLongNames.push_back(wxString::Format(wxT("%s - %s"),mShownCodecNames.back(),wxString::FromUTF8(codec->long_name)));
|
|
}
|
|
}
|
|
}
|
|
// All codecs are compatible with this format
|
|
if (found == 2)
|
|
{
|
|
AVCodec *codec = NULL;
|
|
while ((codec = av_codec_next(codec))!=NULL)
|
|
{
|
|
if (codec->type == AVMEDIA_TYPE_AUDIO && av_codec_is_encoder(codec))
|
|
{
|
|
if (! make_iterator_range( mShownCodecNames )
|
|
.contains( wxString::FromUTF8(codec->name) ) )
|
|
{
|
|
if ((id >= 0) && codec->id == id) index = mShownCodecNames.size();
|
|
mShownCodecNames.push_back(wxString::FromUTF8(codec->name));
|
|
mShownCodecLongNames.push_back(wxString::Format(wxT("%s - %s"),mShownCodecNames.back(),wxString::FromUTF8(codec->long_name)));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
// Format is not found - find format in libavformat and add it's default audio codec
|
|
// This allows us to provide limited support for NEW formats without modifying the compatibility list
|
|
else if (found == 0)
|
|
{
|
|
wxCharBuffer buf = str.ToUTF8();
|
|
AVOutputFormat *format = av_guess_format(buf,NULL,NULL);
|
|
if (format != NULL)
|
|
{
|
|
AVCodec *codec = avcodec_find_encoder(format->audio_codec);
|
|
if (codec != NULL && (codec->type == AVMEDIA_TYPE_AUDIO) && av_codec_is_encoder(codec))
|
|
{
|
|
if ((id >= 0) && codec->id == id) index = mShownCodecNames.size();
|
|
mShownCodecNames.push_back(wxString::FromUTF8(codec->name));
|
|
mShownCodecLongNames.push_back(wxString::Format(wxT("%s - %s"),mShownCodecNames.back(),wxString::FromUTF8(codec->long_name)));
|
|
}
|
|
}
|
|
}
|
|
// Show NEW codec list
|
|
mCodecList->Append(mShownCodecNames);
|
|
|
|
return index;
|
|
}
|
|
|
|
///
|
|
///
|
|
int ExportFFmpegOptions::FetchCompatibleFormatList(AVCodecID id, wxString *selfmt)
|
|
{
|
|
int index = -1;
|
|
mShownFormatNames.clear();
|
|
mShownFormatLongNames.clear();
|
|
mFormatList->Clear();
|
|
AVOutputFormat *ofmt = NULL;
|
|
ofmt = NULL;
|
|
wxArrayString FromList;
|
|
// Find all formats compatible to this codec in compatibility list
|
|
for (int i = 0; CompatibilityList[i].fmt != NULL; i++)
|
|
{
|
|
if (CompatibilityList[i].codec == id || CompatibilityList[i].codec == AV_CODEC_ID_NONE)
|
|
{
|
|
if ((selfmt != NULL) && (*selfmt == CompatibilityList[i].fmt)) index = mShownFormatNames.size();
|
|
FromList.push_back(CompatibilityList[i].fmt);
|
|
mShownFormatNames.push_back(CompatibilityList[i].fmt);
|
|
AVOutputFormat *tofmt = av_guess_format(wxString(CompatibilityList[i].fmt).ToUTF8(),NULL,NULL);
|
|
if (tofmt != NULL) mShownFormatLongNames.push_back(wxString::Format(wxT("%s - %s"),CompatibilityList[i].fmt,wxString::FromUTF8(tofmt->long_name)));
|
|
}
|
|
}
|
|
bool found = false;
|
|
if (selfmt != NULL)
|
|
{
|
|
for (int i = 0; CompatibilityList[i].fmt != NULL; i++)
|
|
{
|
|
if (*selfmt == CompatibilityList[i].fmt)
|
|
{
|
|
found = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
// Format was in the compatibility list
|
|
if (found)
|
|
{
|
|
// Find all formats which have this codec as default and which are not in the list yet and add them too
|
|
while ((ofmt = av_oformat_next(ofmt))!=NULL)
|
|
{
|
|
if (ofmt->audio_codec == id)
|
|
{
|
|
wxString ofmtname = wxString::FromUTF8(ofmt->name);
|
|
found = false;
|
|
for (unsigned int i = 0; i < FromList.size(); i++)
|
|
{
|
|
if (ofmtname == FromList[i])
|
|
{
|
|
found = true;
|
|
break;
|
|
}
|
|
}
|
|
if (!found)
|
|
{
|
|
if ((selfmt != NULL) &&
|
|
(*selfmt == wxString::FromUTF8(ofmt->name)))
|
|
index = mShownFormatNames.size();
|
|
mShownFormatNames.push_back(wxString::FromUTF8(ofmt->name));
|
|
mShownFormatLongNames.push_back(wxString::Format(wxT("%s - %s"),mShownFormatNames.back(),wxString::FromUTF8(ofmt->long_name)));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
mFormatList->Append(mShownFormatNames);
|
|
return index;
|
|
}
|
|
|
|
///
|
|
///
|
|
void ExportFFmpegOptions::OnDeletePreset(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
wxComboBox *preset = dynamic_cast<wxComboBox*>(FindWindowById(FEPresetID,this));
|
|
wxString presetname = preset->GetValue();
|
|
if (presetname.empty())
|
|
{
|
|
AudacityMessageBox(_("You can't delete a preset without name"));
|
|
return;
|
|
}
|
|
|
|
wxString query = wxString::Format(_("Delete preset '%s'?"),presetname);
|
|
int action = AudacityMessageBox(query,_("Confirm Deletion"),wxYES_NO | wxCENTRE);
|
|
if (action == wxNO) return;
|
|
|
|
mPresets->DeletePreset(presetname);
|
|
long index = preset->FindString(presetname);
|
|
preset->SetValue(wxEmptyString);
|
|
preset->Delete(index);
|
|
mPresetNames.erase(
|
|
std::find( mPresetNames.begin(), mPresetNames.end(), presetname )
|
|
);
|
|
}
|
|
|
|
///
|
|
///
|
|
void ExportFFmpegOptions::OnSavePreset(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
wxComboBox *preset = dynamic_cast<wxComboBox*>(FindWindowById(FEPresetID,this));
|
|
wxString name = preset->GetValue();
|
|
if (name.empty())
|
|
{
|
|
AudacityMessageBox(_("You can't save a preset without name"));
|
|
return;
|
|
}
|
|
mPresets->SavePreset(this,name);
|
|
int index = mPresetNames.Index(name,false);
|
|
if (index == -1)
|
|
{
|
|
mPresetNames.push_back(name);
|
|
mPresetCombo->Clear();
|
|
mPresetCombo->Append(mPresetNames);
|
|
mPresetCombo->Select(mPresetNames.Index(name,false));
|
|
}
|
|
}
|
|
|
|
///
|
|
///
|
|
void ExportFFmpegOptions::OnLoadPreset(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
wxComboBox *preset = dynamic_cast<wxComboBox*>(FindWindowById(FEPresetID,this));
|
|
wxString presetname = preset->GetValue();
|
|
|
|
mShownFormatNames = mFormatNames;
|
|
mShownFormatLongNames = mFormatLongNames;
|
|
mFormatList->Clear();
|
|
mFormatList->Append(mFormatNames);
|
|
|
|
mShownCodecNames = mCodecNames;
|
|
mShownCodecLongNames = mCodecLongNames;
|
|
mCodecList->Clear();
|
|
mCodecList->Append(mCodecNames);
|
|
|
|
mPresets->LoadPreset(this,presetname);
|
|
|
|
DoOnFormatList();
|
|
DoOnCodecList();
|
|
}
|
|
|
|
///
|
|
///
|
|
void ExportFFmpegOptions::OnImportPresets(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
wxString path;
|
|
FileDialogWrapper dlg(this,
|
|
_("Select xml file with presets to import"),
|
|
gPrefs->Read(wxT("/FileFormats/FFmpegPresetDir")),
|
|
wxEmptyString,
|
|
wxString(_("XML files (*.xml)|*.xml|All files|*")),
|
|
wxFD_OPEN);
|
|
if (dlg.ShowModal() == wxID_CANCEL) return;
|
|
path = dlg.GetPath();
|
|
mPresets->ImportPresets(path);
|
|
mPresets->GetPresetList(mPresetNames);
|
|
mPresetCombo->Clear();
|
|
mPresetCombo->Append(mPresetNames);
|
|
}
|
|
|
|
///
|
|
///
|
|
void ExportFFmpegOptions::OnExportPresets(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
wxString path;
|
|
FileDialogWrapper dlg(this,
|
|
_("Select xml file to export presets into"),
|
|
gPrefs->Read(wxT("/FileFormats/FFmpegPresetDir")),
|
|
wxEmptyString,
|
|
wxString(_("XML files (*.xml)|*.xml|All files|*")),
|
|
wxFD_SAVE|wxFD_OVERWRITE_PROMPT);
|
|
if (dlg.ShowModal() == wxID_CANCEL) return;
|
|
path = dlg.GetPath();
|
|
mPresets->ExportPresets(path);
|
|
}
|
|
|
|
///
|
|
///
|
|
void ExportFFmpegOptions::OnAllFormats(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
mShownFormatNames = mFormatNames;
|
|
mShownFormatLongNames = mFormatLongNames;
|
|
mFormatList->Clear();
|
|
mFormatList->Append(mFormatNames);
|
|
}
|
|
|
|
///
|
|
///
|
|
void ExportFFmpegOptions::OnAllCodecs(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
mShownCodecNames = mCodecNames;
|
|
mShownCodecLongNames = mCodecLongNames;
|
|
mCodecList->Clear();
|
|
mCodecList->Append(mCodecNames);
|
|
}
|
|
|
|
void ExportFFmpegOptions::EnableDisableControls(AVCodec *cdc, wxString *selfmt)
|
|
{
|
|
int handled = -1;
|
|
for (int i = 0; apptable[i].control != 0; i++)
|
|
{
|
|
if (apptable[i].control != handled)
|
|
{
|
|
bool codec = false;
|
|
bool format = false;
|
|
if (apptable[i].codec == AV_CODEC_ID_NONE) codec = true;
|
|
else if (cdc != NULL && apptable[i].codec == cdc->id) codec = true;
|
|
if (wxString::FromUTF8(apptable[i].format) == wxT("any")) format = true;
|
|
else if (selfmt != NULL &&
|
|
*selfmt == wxString::FromUTF8(apptable[i].format)) format = true;
|
|
if (codec && format)
|
|
{
|
|
handled = apptable[i].control;
|
|
wxWindow *item = FindWindowById(apptable[i].control,this);
|
|
if (item != NULL) item->Enable(apptable[i].enable);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void ExportFFmpegOptions::DoOnFormatList()
|
|
{
|
|
wxString *selfmt = NULL;
|
|
wxString *selfmtlong = NULL;
|
|
FindSelectedFormat(&selfmt, &selfmtlong);
|
|
if (selfmt == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
wxString *selcdc = NULL;
|
|
wxString *selcdclong = NULL;
|
|
FindSelectedCodec(&selcdc, &selcdclong);
|
|
|
|
AVOutputFormat *fmt = av_guess_format(selfmt->ToUTF8(),NULL,NULL);
|
|
if (fmt == NULL)
|
|
{
|
|
//This shouldn't really happen
|
|
mFormatName->SetLabel(wxString(_("Failed to guess format")));
|
|
return;
|
|
}
|
|
mFormatName->SetLabel(wxString::Format(wxT("%s"), *selfmtlong));
|
|
int selcdcid = -1;
|
|
|
|
if (selcdc != NULL)
|
|
{
|
|
AVCodec *cdc = avcodec_find_encoder_by_name(selcdc->ToUTF8());
|
|
if (cdc != NULL)
|
|
{
|
|
selcdcid = cdc->id;
|
|
}
|
|
}
|
|
int newselcdc = FetchCompatibleCodecList(*selfmt, (AVCodecID)selcdcid);
|
|
if (newselcdc >= 0) mCodecList->Select(newselcdc);
|
|
|
|
AVCodec *cdc = NULL;
|
|
if (selcdc != NULL)
|
|
cdc = avcodec_find_encoder_by_name(selcdc->ToUTF8());
|
|
EnableDisableControls(cdc, selfmt);
|
|
Layout();
|
|
Fit();
|
|
return;
|
|
}
|
|
|
|
void ExportFFmpegOptions::DoOnCodecList()
|
|
{
|
|
wxString *selcdc = NULL;
|
|
wxString *selcdclong = NULL;
|
|
FindSelectedCodec(&selcdc, &selcdclong);
|
|
if (selcdc == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
wxString *selfmt = NULL;
|
|
wxString *selfmtlong = NULL;
|
|
FindSelectedFormat(&selfmt, &selfmtlong);
|
|
|
|
AVCodec *cdc = avcodec_find_encoder_by_name(selcdc->ToUTF8());
|
|
if (cdc == NULL)
|
|
{
|
|
//This shouldn't really happen
|
|
mCodecName->SetLabel(wxString(_("Failed to find the codec")));
|
|
return;
|
|
}
|
|
mCodecName->SetLabel(wxString::Format(wxT("[%d] %s"), (int) cdc->id, *selcdclong));
|
|
|
|
if (selfmt != NULL)
|
|
{
|
|
AVOutputFormat *fmt = av_guess_format(selfmt->ToUTF8(),NULL,NULL);
|
|
if (fmt == NULL)
|
|
{
|
|
selfmt = NULL;
|
|
selfmtlong = NULL;
|
|
}
|
|
}
|
|
|
|
int newselfmt = FetchCompatibleFormatList(cdc->id,selfmt);
|
|
if (newselfmt >= 0) mFormatList->Select(newselfmt);
|
|
|
|
EnableDisableControls(cdc, selfmt);
|
|
Layout();
|
|
Fit();
|
|
return;
|
|
}
|
|
|
|
///
|
|
///
|
|
void ExportFFmpegOptions::OnFormatList(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
DoOnFormatList();
|
|
}
|
|
|
|
///
|
|
///
|
|
void ExportFFmpegOptions::OnCodecList(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
DoOnCodecList();
|
|
}
|
|
|
|
///
|
|
///
|
|
void ExportFFmpegOptions::OnOK(wxCommandEvent& WXUNUSED(event))
|
|
{
|
|
int selcdc = mCodecList->GetSelection();
|
|
int selfmt = mFormatList->GetSelection();
|
|
if (selcdc > -1) gPrefs->Write(wxT("/FileFormats/FFmpegCodec"),mCodecList->GetString(selcdc));
|
|
if (selfmt > -1) gPrefs->Write(wxT("/FileFormats/FFmpegFormat"),mFormatList->GetString(selfmt));
|
|
gPrefs->Flush();
|
|
|
|
ShuttleGui S(this, eIsSavingToPrefs);
|
|
PopulateOrExchange(S);
|
|
|
|
gPrefs->Flush();
|
|
|
|
EndModal(wxID_OK);
|
|
|
|
return;
|
|
}
|
|
|
|
#endif
|