Audacity 3.2.0
ExportFFmpegOptions.cpp
Go to the documentation of this file.
1/**********************************************************************
2
3 Audacity: A Digital Audio Editor
4
5 ExportFFmpegOptions.cpp
6
7 Audacity(R) is copyright (c) 1999-2010 Audacity Team.
8 License: GPL v2 or later. See License.txt.
9
10 LRN
11
12 Vitaly Sverchinsky split from ExportFFmpegDialogs.cpp
13
14**********************************************************************/
15
16#include "ExportFFmpegOptions.h"
17
18#include <wx/listbox.h>
19#include <wx/combobox.h>
20#include <wx/stattext.h>
21
22#include "ShuttleGui.h"
23#include "FFmpegPresets.h"
24#include "FFmpegDefines.h"
25#include "AudacityMessageBox.h"
26#include "HelpSystem.h"
27
28#if wxUSE_ACCESSIBILITY
29#include "WindowAccessible.h"
30#endif
31
32BEGIN_EVENT_TABLE(ExportFFmpegOptions, wxDialogWrapper)
35 EVT_LISTBOX(FEFormatID,ExportFFmpegOptions::OnFormatList)
36 EVT_LISTBOX(FECodecID,ExportFFmpegOptions::OnCodecList)
45
46
48CompatibilityEntry ExportFFmpegOptions::CompatibilityList[] =
49{
50 { wxT("adts"), AUDACITY_AV_CODEC_ID_AAC },
51
60 { wxT("aiff"), AUDACITY_AV_CODEC_ID_GSM },
64 { wxT("aiff"), AUDACITY_AV_CODEC_ID_QDM2 },
65
68
82 //{ wxT("asf"), AUDACITY_AV_CODEC_ID_MP2 }, Bug 59
83 { wxT("asf"), AUDACITY_AV_CODEC_ID_MP3 },
84#if LIBAVCODEC_VERSION_MAJOR < 58
86#endif
87 { wxT("asf"), AUDACITY_AV_CODEC_ID_AAC },
93 { wxT("asf"), AUDACITY_AV_CODEC_ID_IMC },
94 { wxT("asf"), AUDACITY_AV_CODEC_ID_AC3 },
95 { wxT("asf"), AUDACITY_AV_CODEC_ID_DTS },
99
104
118 // { wxT("avi"), AUDACITY_AV_CODEC_ID_MP2 }, //Bug 59
119 { wxT("avi"), AUDACITY_AV_CODEC_ID_MP3 },
120#if LIBAVCODEC_VERSION_MAJOR < 58
122#endif
123 { wxT("avi"), AUDACITY_AV_CODEC_ID_AAC },
129 { wxT("avi"), AUDACITY_AV_CODEC_ID_IMC },
130 { wxT("avi"), AUDACITY_AV_CODEC_ID_AC3 },
131 { wxT("avi"), AUDACITY_AV_CODEC_ID_DTS },
132 { wxT("avi"), AUDACITY_AV_CODEC_ID_FLAC },
135
136 { wxT("crc"), AUDACITY_AV_CODEC_ID_NONE },
137
139
140 { wxT("ffm"), AUDACITY_AV_CODEC_ID_NONE },
141
142 { wxT("flv"), AUDACITY_AV_CODEC_ID_MP3 },
147 { wxT("flv"), AUDACITY_AV_CODEC_ID_AAC },
149
150 { wxT("framecrc"), AUDACITY_AV_CODEC_ID_NONE },
151
153
154 { wxT("matroska"), AUDACITY_AV_CODEC_ID_PCM_S16LE },
155 { wxT("matroska"), AUDACITY_AV_CODEC_ID_PCM_U8 },
156 { wxT("matroska"), AUDACITY_AV_CODEC_ID_PCM_S24LE },
157 { wxT("matroska"), AUDACITY_AV_CODEC_ID_PCM_S32LE },
158 { wxT("matroska"), AUDACITY_AV_CODEC_ID_ADPCM_MS },
159 { wxT("matroska"), AUDACITY_AV_CODEC_ID_PCM_ALAW },
160 { wxT("matroska"), AUDACITY_AV_CODEC_ID_PCM_MULAW },
161 { wxT("matroska"), AUDACITY_AV_CODEC_ID_WMAVOICE },
163 { wxT("matroska"), AUDACITY_AV_CODEC_ID_ADPCM_YAMAHA },
164 { wxT("matroska"), AUDACITY_AV_CODEC_ID_TRUESPEECH },
165 { wxT("matroska"), AUDACITY_AV_CODEC_ID_GSM_MS },
166 { wxT("matroska"), AUDACITY_AV_CODEC_ID_ADPCM_G726 },
167 // { wxT("matroska"), AUDACITY_AV_CODEC_ID_MP2 }, // Bug 59
168 { wxT("matroska"), AUDACITY_AV_CODEC_ID_MP3 },
169#if LIBAVCODEC_VERSION_MAJOR < 58
170 { wxT("matroska"), AUDACITY_AV_CODEC_ID_VOXWARE },
171#endif
172 { wxT("matroska"), AUDACITY_AV_CODEC_ID_AAC },
173 { wxT("matroska"), AUDACITY_AV_CODEC_ID_WMAV1 },
174 { wxT("matroska"), AUDACITY_AV_CODEC_ID_WMAV2 },
175 { wxT("matroska"), AUDACITY_AV_CODEC_ID_WMAPRO },
176 { wxT("matroska"), AUDACITY_AV_CODEC_ID_ADPCM_CT },
177 { wxT("matroska"), AUDACITY_AV_CODEC_ID_ATRAC3 },
178 { wxT("matroska"), AUDACITY_AV_CODEC_ID_IMC },
179 { wxT("matroska"), AUDACITY_AV_CODEC_ID_AC3 },
180 { wxT("matroska"), AUDACITY_AV_CODEC_ID_DTS },
181 { wxT("matroska"), AUDACITY_AV_CODEC_ID_FLAC },
182 { wxT("matroska"), AUDACITY_AV_CODEC_ID_ADPCM_SWF },
183 { wxT("matroska"), AUDACITY_AV_CODEC_ID_VORBIS },
184
186
187 { wxT("mov"), AUDACITY_AV_CODEC_ID_PCM_S32BE }, //mov
200 { wxT("mov"), AUDACITY_AV_CODEC_ID_MP3 },
201 { wxT("mov"), AUDACITY_AV_CODEC_ID_AAC },
204 { wxT("mov"), AUDACITY_AV_CODEC_ID_GSM },
205 { wxT("mov"), AUDACITY_AV_CODEC_ID_ALAC },
207 { wxT("mov"), AUDACITY_AV_CODEC_ID_QDM2 },
210 { wxT("mov"), AUDACITY_AV_CODEC_ID_ALAC },
211
212 { wxT("mp4"), AUDACITY_AV_CODEC_ID_AAC },
214 { wxT("mp4"), AUDACITY_AV_CODEC_ID_MP3 },
216
217 { wxT("psp"), AUDACITY_AV_CODEC_ID_AAC },
219 { wxT("psp"), AUDACITY_AV_CODEC_ID_MP3 },
221
222 { wxT("ipod"), AUDACITY_AV_CODEC_ID_AAC },
223 { wxT("ipod"), AUDACITY_AV_CODEC_ID_QCELP },
224 { wxT("ipod"), AUDACITY_AV_CODEC_ID_MP3 },
225 { wxT("ipod"), AUDACITY_AV_CODEC_ID_VORBIS },
226
227 { wxT("3gp"), AUDACITY_AV_CODEC_ID_AAC },
230
231 { wxT("3g2"), AUDACITY_AV_CODEC_ID_AAC },
234
235 { wxT("mp3"), AUDACITY_AV_CODEC_ID_MP3 },
236
237 { wxT("mpeg"), AUDACITY_AV_CODEC_ID_AC3 },
238 { wxT("mpeg"), AUDACITY_AV_CODEC_ID_DTS },
240 //{ wxT("mpeg"), AUDACITY_AV_CODEC_ID_MP2 },// Bug 59
241
242 { wxT("vcd"), AUDACITY_AV_CODEC_ID_AC3 },
243 { wxT("vcd"), AUDACITY_AV_CODEC_ID_DTS },
245 //{ wxT("vcd"), AUDACITY_AV_CODEC_ID_MP2 },// Bug 59
246
247 { wxT("vob"), AUDACITY_AV_CODEC_ID_AC3 },
248 { wxT("vob"), AUDACITY_AV_CODEC_ID_DTS },
250 //{ wxT("vob"), AUDACITY_AV_CODEC_ID_MP2 },// Bug 59
251
252 { wxT("svcd"), AUDACITY_AV_CODEC_ID_AC3 },
253 { wxT("svcd"), AUDACITY_AV_CODEC_ID_DTS },
255 //{ wxT("svcd"), AUDACITY_AV_CODEC_ID_MP2 },// Bug 59
256
257 { wxT("dvd"), AUDACITY_AV_CODEC_ID_AC3 },
258 { wxT("dvd"), AUDACITY_AV_CODEC_ID_DTS },
260 //{ wxT("dvd"), AUDACITY_AV_CODEC_ID_MP2 },// Bug 59
261
275 //{ wxT("nut"), AUDACITY_AV_CODEC_ID_MP2 },// Bug 59
276 { wxT("nut"), AUDACITY_AV_CODEC_ID_MP3 },
277 #if LIBAVCODEC_VERSION_MAJOR < 58
279 #endif
280 { wxT("nut"), AUDACITY_AV_CODEC_ID_AAC },
286 { wxT("nut"), AUDACITY_AV_CODEC_ID_IMC },
287 { wxT("nut"), AUDACITY_AV_CODEC_ID_AC3 },
288 { wxT("nut"), AUDACITY_AV_CODEC_ID_DTS },
289 { wxT("nut"), AUDACITY_AV_CODEC_ID_FLAC },
292
294 { wxT("ogg"), AUDACITY_AV_CODEC_ID_FLAC },
295
296 { wxT("ac3"), AUDACITY_AV_CODEC_ID_AC3 },
297
298 { wxT("dts"), AUDACITY_AV_CODEC_ID_DTS },
299
300 { wxT("flac"), AUDACITY_AV_CODEC_ID_FLAC },
301
303
304 { wxT("rm"), AUDACITY_AV_CODEC_ID_AC3 },
305
306 { wxT("swf"), AUDACITY_AV_CODEC_ID_MP3 },
307
308 { wxT("avm2"), AUDACITY_AV_CODEC_ID_MP3 },
309
311
325 //{ wxT("wav"), AUDACITY_AV_CODEC_ID_MP2 }, Bug 59 - It crashes.
326 { wxT("wav"), AUDACITY_AV_CODEC_ID_MP3 },
327#if LIBAVCODEC_VERSION_MAJOR < 58
329#endif
330 { wxT("wav"), AUDACITY_AV_CODEC_ID_AAC },
331 // { wxT("wav"), AUDACITY_AV_CODEC_ID_WMAV1 },
332 // { wxT("wav"), AUDACITY_AV_CODEC_ID_WMAV2 },
336 { wxT("wav"), AUDACITY_AV_CODEC_ID_IMC },
337 { wxT("wav"), AUDACITY_AV_CODEC_ID_AC3 },
338 //{ wxT("wav"), AUDACITY_AV_CODEC_ID_DTS },
339 { wxT("wav"), AUDACITY_AV_CODEC_ID_FLAC },
342
344};
345
347// The FF_PROFILE_* enumeration is defined in the ffmpeg library
348// PRL: I can't find where this preference is used!
349ChoiceSetting AACProfiles { wxT("/FileFormats/FFmpegAACProfile"),
350 {
351 {wxT("1") /*FF_PROFILE_AAC_LOW*/, XO("LC")},
352 {wxT("0") /*FF_PROFILE_AAC_MAIN*/, XO("Main")},
353 // {wxT("2") /*FF_PROFILE_AAC_SSR*/, XO("SSR")}, //SSR is not supported
354 {wxT("3") /*FF_PROFILE_AAC_LTP*/, XO("LTP")},
355 },
356 0, // "1"
357};
358
361{
362 {FMT_M4A, wxT("M4A"), wxT("m4a"), wxT("ipod"), 48, AV_CANMETA, true, XO("M4A (AAC) Files (FFmpeg)"), AUDACITY_AV_CODEC_ID_AAC, true},
363 {FMT_AC3, wxT("AC3"), wxT("ac3"), wxT("ac3"), 7, AV_VERSION_INT(0,0,0), false, XO("AC3 Files (FFmpeg)"), AUDACITY_AV_CODEC_ID_AC3, true},
364 {FMT_AMRNB, wxT("AMRNB"), wxT("amr"), wxT("amr"), 1, AV_VERSION_INT(0,0,0), false, XO("AMR (narrow band) Files (FFmpeg)"), AUDACITY_AV_CODEC_ID_AMR_NB, true},
365 #ifdef SHOW_FFMPEG_OPUS_EXPORT
366 {FMT_OPUS, wxT("OPUS"), wxT("opus"), wxT("opus"), 255, AV_CANMETA, true, XO("Opus (OggOpus) Files (FFmpeg)"), AUDACITY_AV_CODEC_ID_OPUS, true},
367 #endif
368 {FMT_WMA2, wxT("WMA"), wxT("wma"), wxT("asf"), 2, AV_VERSION_INT(52,53,0), false, XO("WMA (version 2) Files (FFmpeg)"), AUDACITY_AV_CODEC_ID_WMAV2, true},
369 {FMT_OTHER, wxT("FFMPEG"), wxT(""), wxT(""), 255, AV_CANMETA, true, XO("Custom FFmpeg Export"), AUDACITY_AV_CODEC_ID_NONE, true}
370};
371
380{
381 {TRUE,FEQualityID,AUDACITY_AV_CODEC_ID_AAC,"any"},
382 {TRUE,FEQualityID,AUDACITY_AV_CODEC_ID_MP3,"any"},
383 {TRUE,FEQualityID,AUDACITY_AV_CODEC_ID_VORBIS,"any"},
384 {FALSE,FEQualityID,AUDACITY_AV_CODEC_ID_NONE,"any"},
385
386 {TRUE,FECutoffID,AUDACITY_AV_CODEC_ID_AC3,"any"},
387 {TRUE,FECutoffID,AUDACITY_AV_CODEC_ID_AAC,"any"},
388 {TRUE,FECutoffID,AUDACITY_AV_CODEC_ID_VORBIS,"any"},
389 {FALSE,FECutoffID,AUDACITY_AV_CODEC_ID_NONE,"any"},
390
391 {TRUE,FEFrameSizeID,AUDACITY_AV_CODEC_ID_FLAC,"any"},
392 {FALSE,FEFrameSizeID,AUDACITY_AV_CODEC_ID_NONE,"any"},
393
394 {TRUE,FEProfileID,AUDACITY_AV_CODEC_ID_AAC,"any"},
395 {FALSE,FEProfileID,AUDACITY_AV_CODEC_ID_NONE,"any"},
396
397 {TRUE,FECompLevelID,AUDACITY_AV_CODEC_ID_FLAC,"any"},
398 {FALSE,FECompLevelID,AUDACITY_AV_CODEC_ID_NONE,"any"},
399
400 {TRUE,FEUseLPCID,AUDACITY_AV_CODEC_ID_FLAC,"any"},
401 {FALSE,FEUseLPCID,AUDACITY_AV_CODEC_ID_NONE,"any"},
402
403 {TRUE,FELPCCoeffsID,AUDACITY_AV_CODEC_ID_FLAC,"any"},
404 {FALSE,FELPCCoeffsID,AUDACITY_AV_CODEC_ID_NONE,"any"},
405
406 {TRUE,FEMinPredID,AUDACITY_AV_CODEC_ID_FLAC,"any"},
407 {FALSE,FEMinPredID,AUDACITY_AV_CODEC_ID_NONE,"any"},
408
409 {TRUE,FEMaxPredID,AUDACITY_AV_CODEC_ID_FLAC,"any"},
410 {FALSE,FEMaxPredID,AUDACITY_AV_CODEC_ID_NONE,"any"},
411
412 {TRUE,FEPredOrderID,AUDACITY_AV_CODEC_ID_FLAC,"any"},
413 {FALSE,FEPredOrderID,AUDACITY_AV_CODEC_ID_NONE,"any"},
414
415 {TRUE,FEMinPartOrderID,AUDACITY_AV_CODEC_ID_FLAC,"any"},
416 {FALSE,FEMinPartOrderID,AUDACITY_AV_CODEC_ID_NONE,"any"},
417
418 {TRUE,FEMaxPartOrderID,AUDACITY_AV_CODEC_ID_FLAC,"any"},
419 {FALSE,FEMaxPartOrderID,AUDACITY_AV_CODEC_ID_NONE,"any"},
420
421 {TRUE,FEMuxRateID,AUDACITY_AV_CODEC_ID_NONE,"mpeg"},
422 {TRUE,FEMuxRateID,AUDACITY_AV_CODEC_ID_NONE,"vcd"},
423 {TRUE,FEMuxRateID,AUDACITY_AV_CODEC_ID_NONE,"vob"},
424 {TRUE,FEMuxRateID,AUDACITY_AV_CODEC_ID_NONE,"svcd"},
425 {TRUE,FEMuxRateID,AUDACITY_AV_CODEC_ID_NONE,"dvd"},
426 {FALSE,FEMuxRateID,AUDACITY_AV_CODEC_ID_NONE,"any"},
427
428 {TRUE,FEPacketSizeID,AUDACITY_AV_CODEC_ID_NONE,"mpeg"},
429 {TRUE,FEPacketSizeID,AUDACITY_AV_CODEC_ID_NONE,"vcd"},
430 {TRUE,FEPacketSizeID,AUDACITY_AV_CODEC_ID_NONE,"vob"},
431 {TRUE,FEPacketSizeID,AUDACITY_AV_CODEC_ID_NONE,"svcd"},
432 {TRUE,FEPacketSizeID,AUDACITY_AV_CODEC_ID_NONE,"dvd"},
433 {FALSE,FEPacketSizeID,AUDACITY_AV_CODEC_ID_NONE,"any"},
434
435 {TRUE,FELanguageID,AUDACITY_AV_CODEC_ID_NONE,"matroska"},
436 {TRUE,FELanguageID,AUDACITY_AV_CODEC_ID_NONE,"mov"},
437 {TRUE,FELanguageID,AUDACITY_AV_CODEC_ID_NONE,"3gp"},
438 {TRUE,FELanguageID,AUDACITY_AV_CODEC_ID_NONE,"mp4"},
439 {TRUE,FELanguageID,AUDACITY_AV_CODEC_ID_NONE,"psp"},
440 {TRUE,FELanguageID,AUDACITY_AV_CODEC_ID_NONE,"3g2"},
441 {TRUE,FELanguageID,AUDACITY_AV_CODEC_ID_NONE,"ipod"},
442 {TRUE,FELanguageID,AUDACITY_AV_CODEC_ID_NONE,"mpegts"},
443 {FALSE,FELanguageID,AUDACITY_AV_CODEC_ID_NONE,"any"},
444
445 {TRUE,FEBitReservoirID,AUDACITY_AV_CODEC_ID_MP3,"any"},
446 {TRUE,FEBitReservoirID,AUDACITY_AV_CODEC_ID_WMAV1,"any"},
447 {TRUE,FEBitReservoirID,AUDACITY_AV_CODEC_ID_WMAV2,"any"},
448 {FALSE,FEBitReservoirID,AUDACITY_AV_CODEC_ID_NONE,"any"},
449
450 {TRUE,FEVariableBlockLenID,AUDACITY_AV_CODEC_ID_WMAV1,"any"},
451 {TRUE,FEVariableBlockLenID,AUDACITY_AV_CODEC_ID_WMAV2,"any"},
452 {FALSE,FEVariableBlockLenID,AUDACITY_AV_CODEC_ID_NONE,"any"},
453
455};
456
457namespace {
458
461 XO("Estimate"),
462 XO("2-level"),
463 XO("4-level"),
464 XO("8-level"),
465 XO("Full search"),
466 XO("Log search"),
467};
468
469}
470
471
472
474{
475}
476
478: wxDialogWrapper(parent, wxID_ANY,
479 XO("Configure custom FFmpeg options"))
480{
481 SetName();
484 //FFmpegLibsInst()->LoadLibs(NULL,true); //Loaded at startup or from Prefs now
485
486 mPresets = std::make_unique<FFmpegPresets>();
487 mPresets->GetPresetList(mPresetNames);
488
489 if (mFFmpeg)
490 {
493
495
496 //Select the format that was selected last time this dialog was closed
497 mFormatList->Select(mFormatList->FindString(gPrefs->Read(wxT("/FileFormats/FFmpegFormat"))));
499
500 //Select the codec that was selected last time this dialog was closed
501 auto codec = mFFmpeg->CreateEncoder(gPrefs->Read(wxT("/FileFormats/FFmpegCodec")).ToUTF8());
502
503 if (codec != nullptr)
504 mCodecList->Select(mCodecList->FindString(wxString::FromUTF8(codec->GetName())));
505
507 }
508
509}
510
514{
515 if (!mFFmpeg)
516 return;
517
518 for (auto ofmt : mFFmpeg->GetOutputFormats())
519 {
520 // Any audio-capable format has default audio codec.
521 // If it doesn't, then it doesn't supports any audio codecs
522 if (ofmt->GetAudioCodec() != AUDACITY_AV_CODEC_ID_NONE)
523 {
524 mFormatNames.push_back(wxString::FromUTF8(ofmt->GetName()));
525 mFormatLongNames.push_back(wxString::Format(wxT("%s - %s"),mFormatNames.back(),wxString::FromUTF8(ofmt->GetLongName())));
526 }
527 }
528 // Show all formats
531}
532
536{
537 if (!mFFmpeg)
538 return;
539 // Enumerate all codecs
540 std::unique_ptr<AVCodecWrapper> codec;
541 for (auto codec : mFFmpeg->GetCodecs())
542 {
543 // We're only interested in audio and only in encoders
544 if (codec->IsAudio() && mFFmpeg->av_codec_is_encoder(codec->GetWrappedValue()))
545 {
546 // MP2 Codec is broken. Don't allow it.
547 if( codec->GetId() == mFFmpeg->GetAVCodecID(AUDACITY_AV_CODEC_ID_MP2))
548 continue;
549
550 mCodecNames.push_back(wxString::FromUTF8(codec->GetName()));
551 mCodecLongNames.push_back(wxString::Format(wxT("%s - %s"),mCodecNames.back(),wxString::FromUTF8(codec->GetLongName())));
552 }
553 }
554 // Show all codecs
557}
558
562{
563 IntSetting PredictionOrderSetting{ L"/FileFormats/FFmpegPredOrderMethod",
564 4 }; // defaults to Full search
565
566 S.StartVerticalLay(1);
567 S.StartMultiColumn(1, wxEXPAND);
568 {
569 S.SetStretchyRow(3);
570 S.StartMultiColumn(7, wxEXPAND);
571 {
572 S.SetStretchyCol(1);
573 mPresetCombo = S.Id(FEPresetID).AddCombo(XXO("Preset:"), gPrefs->Read(wxT("/FileFormats/FFmpegPreset"),wxEmptyString), mPresetNames);
574 S.Id(FELoadPresetID).AddButton(XXO("Load Preset"));
575 S.Id(FESavePresetID).AddButton(XXO("Save Preset"));
576 S.Id(FEDeletePresetID).AddButton(XXO("Delete Preset"));
577 S.Id(FEImportPresetsID).AddButton(XXO("Import Presets"));
578 S.Id(FEExportPresetsID).AddButton(XXO("Export Presets"));
579 }
580 S.EndMultiColumn();
581 S.StartMultiColumn(4, wxALIGN_LEFT);
582 {
583 S.SetStretchyCol(1);
584 S.SetStretchyCol(3);
585 S.Id(FEFormatLabelID).AddFixedText(XO("Format:"));
586 mFormatName = S.Id(FEFormatNameID).AddVariableText( {} );
587 /* i18n-hint: "codec" is short for a "coder-decoder" algorithm */
588 S.Id(FECodecLabelID).AddFixedText(XO("Codec:"));
589 mCodecName = S.Id(FECodecNameID).AddVariableText( {} );
590 }
591 S.EndMultiColumn();
592 S.AddVariableText(XO(
593"Not all formats and codecs are compatible. Nor are all option combinations compatible with all codecs."),
594 false);
595 S.StartMultiColumn(2, wxEXPAND);
596 {
597 S.StartMultiColumn(2, wxEXPAND);
598 {
599 S.SetStretchyRow(1);
600 S.Id(FEAllFormatsID).AddButton(XXO("Show All Formats"));
601 S.Id(FEAllCodecsID).AddButton(XXO("Show All Codecs"));
602 mFormatList = S.Id(FEFormatID).Name(XO("Formats")).
603 AddListBox(mFormatNames);
604 mFormatList->DeselectAll();
605 mCodecList = S.Id(FECodecID).Name(XO("Codecs")).
606 AddListBox(mCodecNames);
607 mCodecList->DeselectAll();
608#if wxUSE_ACCESSIBILITY
609 // so that names can be set on standard controls
612#endif
613 }
614 S.EndMultiColumn();
615 S.StartVerticalLay();
616 {
617 //S.StartScroller( );
618 S.SetBorder( 3 );
619 S.StartStatic(XO("General Options"), 0);
620 {
621 S.StartMultiColumn(8, wxEXPAND);
622 {
623 S.Id(FELanguageID)
624 .ToolTip(XO("ISO 639 3-letter language code\nOptional\nempty - automatic"))
625 .TieTextBox(XXO("Language:"), {wxT("/FileFormats/FFmpegLanguage"), wxEmptyString}, 9);
626
627 S.AddSpace( 20,0 );
628 S.AddVariableText(XO("Bit Reservoir"));
629 S.Id(FEBitReservoirID).TieCheckBox( {}, {wxT("/FileFormats/FFmpegBitReservoir"), true});
630
631 S.AddSpace( 20,0 );
632 S.AddVariableText(XO("VBL"));
633 S.Id(FEVariableBlockLenID).TieCheckBox( {}, {wxT("/FileFormats/FFmpegVariableBlockLen"), true});
634 }
635 S.EndMultiColumn();
636 S.StartMultiColumn(4, wxALIGN_LEFT);
637 {
638 S.Id(FETagID)
639 /* i18n-hint: "codec" is short for a "coder-decoder" algorithm */
640 .ToolTip(XO("Codec tag (FOURCC)\nOptional\nempty - automatic"))
641 .TieTextBox(XXO("Tag:"), {wxT("/FileFormats/FFmpegTag"), wxEmptyString}, 4);
642
643 S.Id(FEBitrateID)
644 .ToolTip(XO("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"))
645 .TieSpinCtrl(XXO("Bit Rate:"), {wxT("/FileFormats/FFmpegBitRate"), 0}, 1000000, 0);
646
647 S.Id(FEQualityID)
648 .ToolTip(XO("Overall quality, used differently by different codecs\nRequired for vorbis\n0 - automatic\n-1 - off (use bitrate instead)"))
649 .TieSpinCtrl(XXO("Quality:"), {wxT("/FileFormats/FFmpegQuality"), 0}, 500, -1);
650
651 S.Id(FESampleRateID)
652 .ToolTip(XO("Sample rate (Hz)\n0 - don't change sample rate"))
653 .TieSpinCtrl(XXO("Sample Rate:"), {wxT("/FileFormats/FFmpegSampleRate"), 0}, 200000, 0);
654
655 S.Id(FECutoffID)
656 .ToolTip(XO("Audio cutoff bandwidth (Hz)\nOptional\n0 - automatic"))
657 .TieSpinCtrl(XXO("Cutoff:"), {wxT("/FileFormats/FFmpegCutOff"), 0}, 10000000, 0);
658
659 // PRL: As commented elsewhere, this preference does nothing
660 S.Id(FEProfileID)
661 .ToolTip(XO("AAC Profile\nLow Complexity - default\nMost players won't play anything other than LC"))
662 .MinSize( { 100, -1 } )
663 .TieChoice(XXO("Profile:"), AACProfiles);
664 }
665 S.EndMultiColumn();
666 }
667 S.EndStatic();
668 S.StartStatic(XO("FLAC options"),0);
669 {
670 S.StartMultiColumn(4, wxALIGN_LEFT);
671 {
672 S
673 .ToolTip(XO("Compression level\nRequired for FLAC\n-1 - automatic\nmin - 0 (fast encoding, large output file)\nmax - 10 (slow encoding, small output file)"))
674 .Id(FECompLevelID).TieSpinCtrl(XXO("Compression:"), {wxT("/FileFormats/FFmpegCompLevel"), 0}, 10, -1);
675
676 S.Id(FEFrameSizeID)
677 .ToolTip(XO("Frame size\nOptional\n0 - default\nmin - 16\nmax - 65535"))
678 .TieSpinCtrl(XXO("Frame:"), {wxT("/FileFormats/FFmpegFrameSize"), 0}, 65535, 0);
679
680 S.Id(FELPCCoeffsID)
681 .ToolTip(XO("LPC coefficients precision\nOptional\n0 - default\nmin - 1\nmax - 15"))
682 .TieSpinCtrl(XXO("LPC"), {wxT("/FileFormats/FFmpegLPCCoefPrec"), 0}, 15, 0);
683
684 S.Id(FEPredOrderID)
685 .ToolTip(XO("Prediction Order Method\nEstimate - fastest, lower compression\nLog search - slowest, best compression\nFull search - default"))
686 .MinSize( { 100, -1 } )
687 .TieNumberAsChoice(
688 XXO("PdO Method:"),
689 PredictionOrderSetting,
691 );
692
693 S.Id(FEMinPredID)
694 .ToolTip(XO("Minimal prediction order\nOptional\n-1 - default\nmin - 0\nmax - 32 (with LPC) or 4 (without LPC)"))
695 .TieSpinCtrl(XXO("Min. PdO"), {wxT("/FileFormats/FFmpegMinPredOrder"), -1}, 32, -1);
696
697 S.Id(FEMaxPredID)
698 .ToolTip(XO("Maximal prediction order\nOptional\n-1 - default\nmin - 0\nmax - 32 (with LPC) or 4 (without LPC)"))
699 .TieSpinCtrl(XXO("Max. PdO"), {wxT("/FileFormats/FFmpegMaxPredOrder"), -1}, 32, -1);
700
701 S.Id(FEMinPartOrderID)
702 .ToolTip(XO("Minimal partition order\nOptional\n-1 - default\nmin - 0\nmax - 8"))
703 .TieSpinCtrl(XXO("Min. PtO"), {wxT("/FileFormats/FFmpegMinPartOrder"), -1}, 8, -1);
704
705 S.Id(FEMaxPartOrderID)
706 .ToolTip(XO("Maximal partition order\nOptional\n-1 - default\nmin - 0\nmax - 8"))
707 .TieSpinCtrl(XXO("Max. PtO"), {wxT("/FileFormats/FFmpegMaxPartOrder"), -1}, 8, -1);
708
709 /* i18n-hint: Abbreviates "Linear Predictive Coding",
710 but this text needs to be kept very short */
711 S.AddVariableText(XO("Use LPC"));
712 // PRL: This preference is not used anywhere!
713 S.Id(FEUseLPCID).TieCheckBox( {}, {wxT("/FileFormats/FFmpegUseLPC"), true});
714 }
715 S.EndMultiColumn();
716 }
717 S.EndStatic();
718 S.StartStatic(XO("MPEG container options"),0);
719 {
720 S.StartMultiColumn(4, wxALIGN_LEFT);
721 {
722 S.Id(FEMuxRateID)
723 .ToolTip(XO("Maximum bit rate of the multiplexed stream\nOptional\n0 - default"))
724 /* i18n-hint: 'mux' is short for multiplexor, a device that selects between several inputs
725 'Mux Rate' is a parameter that has some bearing on compression ratio for MPEG
726 it has a hard to predict effect on the degree of compression */
727 .TieSpinCtrl(XXO("Mux Rate:"), {wxT("/FileFormats/FFmpegMuxRate"), 0}, 10000000, 0);
728
729 S.Id(FEPacketSizeID)
730 /* i18n-hint: 'Packet Size' is a parameter that has some bearing on compression ratio for MPEG
731 compression. It measures how big a chunk of audio is compressed in one piece. */
732 .ToolTip(XO("Packet size\nOptional\n0 - default"))
733 /* i18n-hint: 'Packet Size' is a parameter that has some bearing on compression ratio for MPEG
734 compression. It measures how big a chunk of audio is compressed in one piece. */
735 .TieSpinCtrl(XXO("Packet Size:"), {wxT("/FileFormats/FFmpegPacketSize"), 0}, 10000000, 0);
736 }
737 S.EndMultiColumn();
738 }
739 S.EndStatic();
740 //S.EndScroller();
741 S.SetBorder( 5 );
742 S.AddStandardButtons(eOkButton | eCancelButton | eHelpButton );
743 }
744 S.EndVerticalLay();
745 }
746 S.EndMultiColumn();
747 }
748 S.EndMultiColumn();
749 S.EndVerticalLay();
750
751 Layout();
752 Fit();
753 SetMinSize(GetSize());
754 Center();
755
756 return;
757}
758
761void ExportFFmpegOptions::FindSelectedFormat(wxString **name, wxString **longname)
762{
763 // Get current selection
764 wxArrayInt selections;
765 int n = mFormatList->GetSelections(selections);
766 if (n <= 0) return;
767
768 // Get selected format short name
769 wxString selfmt = mFormatList->GetString(selections[0]);
770
771 // Find its index
772 int nFormat = make_iterator_range( mFormatNames ).index( selfmt );
773 if (nFormat == wxNOT_FOUND) return;
774
775 // Return short name and description
776 if (name != NULL) *name = &mFormatNames[nFormat];
777 if (longname != NULL) *longname = &mFormatLongNames[nFormat];
778 return;
779}
782void ExportFFmpegOptions::FindSelectedCodec(wxString **name, wxString **longname)
783{
784 // Get current selection
785 wxArrayInt selections;
786 int n = mCodecList->GetSelections(selections);
787 if (n <= 0) return;
788
789 // Get selected codec short name
790 wxString selcdc = mCodecList->GetString(selections[0]);
791
792 // Find its index
793 int nCodec = make_iterator_range( mCodecNames ).index( selcdc );
794 if (nCodec == wxNOT_FOUND) return;
795
796 // Return short name and description
797 if (name != NULL) *name = &mCodecNames[nCodec];
798 if (longname != NULL) *longname = &mCodecLongNames[nCodec];
799}
800
804{
805 const auto ffmpegId = mFFmpeg->GetAVCodecID(id);
806
807 // By default assume that id is not in the list
808 int index = -1;
809 // By default no codecs are compatible (yet)
810 mShownCodecNames.clear();
811 mShownCodecLongNames.clear();
812 // Clear the listbox
813 mCodecList->Clear();
814 // Zero - format is not found at all
815 int found = 0;
816 wxString str(fmt);
817 for (int i = 0; CompatibilityList[i].fmt != NULL; i++)
818 {
819 if (str == CompatibilityList[i].fmt)
820 {
821 // Format is found in the list
822 found = 1;
823 if (CompatibilityList[i].codec.value == AUDACITY_AV_CODEC_ID_NONE)
824 {
825 // Format is found in the list and it is compatible with AUDACITY_AV_CODEC_ID_NONE (means that it is compatible to anything)
826 found = 2;
827 break;
828 }
829 // Find the codec, that is claimed to be compatible
830 std::unique_ptr<AVCodecWrapper> codec = mFFmpeg->CreateEncoder(mFFmpeg->GetAVCodecID(CompatibilityList[i].codec));
831 // If it exists, is audio and has encoder
832 if (codec != NULL && codec->IsAudio() && mFFmpeg->av_codec_is_encoder(codec->GetWrappedValue()))
833 {
834 // If it was selected - remember its NEW index
835 if ((ffmpegId >= 0) && codec->GetId() == ffmpegId)
836 index = mShownCodecNames.size();
837
838 mShownCodecNames.push_back(wxString::FromUTF8(codec->GetName()));
839 mShownCodecLongNames.push_back(wxString::Format(wxT("%s - %s"),mShownCodecNames.back(),wxString::FromUTF8(codec->GetLongName())));
840 }
841 }
842 }
843 // All codecs are compatible with this format
844 if (found == 2)
845 {
846 std::unique_ptr<AVCodecWrapper> codec;
847 for (auto codec : mFFmpeg->GetCodecs())
848 {
849 if (codec->IsAudio() && mFFmpeg->av_codec_is_encoder(codec->GetWrappedValue()))
850 {
851 // MP2 is broken.
852 if( codec->GetId() == mFFmpeg->GetAVCodecID(AUDACITY_AV_CODEC_ID_MP2) )
853 continue;
854
856 .contains( wxString::FromUTF8(codec->GetName()) ) )
857 {
858 if ((ffmpegId >= 0) && codec->GetId() == ffmpegId)
859 index = mShownCodecNames.size();
860
861 mShownCodecNames.push_back(wxString::FromUTF8(codec->GetName()));
862 mShownCodecLongNames.push_back(wxString::Format(wxT("%s - %s"),mShownCodecNames.back(),wxString::FromUTF8(codec->GetLongName())));
863 }
864 }
865 }
866 }
867 // Format is not found - find format in libavformat and add its default audio codec
868 // This allows us to provide limited support for NEW formats without modifying the compatibility list
869 else if (found == 0)
870 {
871 wxCharBuffer buf = str.ToUTF8();
872 auto format = mFFmpeg->GuessOutputFormat(buf, nullptr, nullptr);
873
874 if (format != nullptr)
875 {
876 auto codec = mFFmpeg->CreateEncoder(format->GetAudioCodec());
877
878 if (
879 codec != nullptr && codec->IsAudio() && mFFmpeg->av_codec_is_encoder(codec->GetWrappedValue()))
880 {
881 if ((ffmpegId >= 0) && codec->GetId() == ffmpegId)
882 index = mShownCodecNames.size();
883
884 mShownCodecNames.push_back(wxString::FromUTF8(codec->GetName()));
885 mShownCodecLongNames.push_back(wxString::Format(wxT("%s - %s"),mShownCodecNames.back(),wxString::FromUTF8(codec->GetLongName())));
886 }
887 }
888 }
889 // Show NEW codec list
891
892 return index;
893}
894
898 AudacityAVCodecID id, wxString* selfmt)
899{
900 int index = -1;
901 mShownFormatNames.clear();
902 mShownFormatLongNames.clear();
903 mFormatList->Clear();
904
905 wxArrayString FromList;
906 // Find all formats compatible to this codec in compatibility list
907 for (int i = 0; CompatibilityList[i].fmt != NULL; i++)
908 {
909 if (CompatibilityList[i].codec == id || (CompatibilityList[i].codec.value == AUDACITY_AV_CODEC_ID_NONE) )
910 {
911 if ((selfmt != NULL) && (*selfmt == CompatibilityList[i].fmt)) index = mShownFormatNames.size();
912 FromList.push_back(CompatibilityList[i].fmt);
913 mShownFormatNames.push_back(CompatibilityList[i].fmt);
914 auto tofmt = mFFmpeg->GuessOutputFormat(
915 wxString(CompatibilityList[i].fmt).ToUTF8(), nullptr, nullptr);
916
917 if (tofmt != NULL)
918 {
919 mShownFormatLongNames.push_back(wxString::Format(
920 wxT("%s - %s"), CompatibilityList[i].fmt,
921 wxString::FromUTF8(tofmt->GetLongName())));
922 }
923 }
924 }
925 bool found = false;
926 if (selfmt != NULL)
927 {
928 for (int i = 0; CompatibilityList[i].fmt != NULL; i++)
929 {
930 if (*selfmt == CompatibilityList[i].fmt)
931 {
932 found = true;
933 break;
934 }
935 }
936 }
937 // Format was in the compatibility list
938 if (found)
939 {
940 // Find all formats which have this codec as default and which are not in the list yet and add them too
941 for (auto ofmt : mFFmpeg->GetOutputFormats())
942 {
943 if (ofmt->GetAudioCodec() == mFFmpeg->GetAVCodecID(id))
944 {
945 wxString ofmtname = wxString::FromUTF8(ofmt->GetName());
946 found = false;
947 for (unsigned int i = 0; i < FromList.size(); i++)
948 {
949 if (ofmtname == FromList[i])
950 {
951 found = true;
952 break;
953 }
954 }
955 if (!found)
956 {
957 if ((selfmt != NULL) &&
958 (*selfmt == wxString::FromUTF8(ofmt->GetName())))
959 index = mShownFormatNames.size();
960
961 mShownFormatNames.push_back(wxString::FromUTF8(ofmt->GetName()));
962
963 mShownFormatLongNames.push_back(wxString::Format(
964 wxT("%s - %s"), mShownFormatNames.back(),
965 wxString::FromUTF8(ofmt->GetLongName())));
966 }
967 }
968 }
969 }
971 return index;
972}
973
976void ExportFFmpegOptions::OnDeletePreset(wxCommandEvent& WXUNUSED(event))
977{
978 wxComboBox *preset = dynamic_cast<wxComboBox*>(FindWindowById(FEPresetID,this));
979 wxString presetname = preset->GetValue();
980 if (presetname.empty())
981 {
982 AudacityMessageBox( XO("You can't delete a preset without name") );
983 return;
984 }
985
986 auto query = XO("Delete preset '%s'?").Format( presetname );
987 int action = AudacityMessageBox(
988 query,
989 XO("Confirm Deletion"),
990 wxYES_NO | wxCENTRE);
991 if (action == wxNO) return;
992
993 mPresets->DeletePreset(presetname);
994 long index = preset->FindString(presetname);
995 preset->SetValue(wxEmptyString);
996 preset->Delete(index);
997 mPresetNames.erase(
998 std::find( mPresetNames.begin(), mPresetNames.end(), presetname )
999 );
1000}
1001
1004void ExportFFmpegOptions::OnSavePreset(wxCommandEvent& WXUNUSED(event))
1005{ const bool kCheckForOverwrite = true;
1006 SavePreset(kCheckForOverwrite);
1007}
1008
1009// Return false if failed to save.
1010bool ExportFFmpegOptions::SavePreset(bool bCheckForOverwrite)
1011{
1012 wxComboBox *preset = dynamic_cast<wxComboBox*>(FindWindowById(FEPresetID,this));
1013 wxString name = preset->GetValue();
1014 if (name.empty())
1015 {
1016 AudacityMessageBox( XO("You can't save a preset without a name") );
1017 return false;
1018 }
1019 if( bCheckForOverwrite && !mPresets->OverwriteIsOk(name))
1020 return false;
1021 if( !mPresets->SavePreset(this,name) )
1022 return false;
1023 int index = mPresetNames.Index(name,false);
1024 if (index == -1)
1025 {
1026 mPresetNames.push_back(name);
1027 mPresetCombo->Clear();
1028 mPresetCombo->Append(mPresetNames);
1029 mPresetCombo->Select(mPresetNames.Index(name,false));
1030 }
1031 return true;
1032}
1033
1036void ExportFFmpegOptions::OnLoadPreset(wxCommandEvent& WXUNUSED(event))
1037{
1038 wxComboBox *preset = dynamic_cast<wxComboBox*>(FindWindowById(FEPresetID,this));
1039 wxString presetname = preset->GetValue();
1040
1043 mFormatList->Clear();
1044 mFormatList->Append(mFormatNames);
1045
1048 mCodecList->Clear();
1049 mCodecList->Append(mCodecNames);
1050
1051 mPresets->LoadPreset(this,presetname);
1052
1054 DoOnCodecList();
1055}
1056
1058{
1059 static const FileNames::FileTypes result{
1061 return result;
1062};
1063
1066void ExportFFmpegOptions::OnImportPresets(wxCommandEvent& WXUNUSED(event))
1067{
1068 wxString path;
1069 FileDialogWrapper dlg(this,
1070 XO("Select xml file with presets to import"),
1071 gPrefs->Read(wxT("/FileFormats/FFmpegPresetDir")),
1072 wxEmptyString,
1073 FileTypes(),
1074 wxFD_OPEN);
1075 if (dlg.ShowModal() == wxID_CANCEL) return;
1076 path = dlg.GetPath();
1077 mPresets->ImportPresets(path);
1078 mPresets->GetPresetList(mPresetNames);
1079 mPresetCombo->Clear();
1080 mPresetCombo->Append(mPresetNames);
1081}
1082
1085void ExportFFmpegOptions::OnExportPresets(wxCommandEvent& WXUNUSED(event))
1086{
1087 const bool kCheckForOverwrite = true;
1088 // Bug 1180 save any pending preset before exporting the lot.
1089 // If saving fails, don't try to export.
1090 if( !SavePreset(!kCheckForOverwrite) )
1091 return;
1092
1093 wxArrayString presets;
1094 mPresets->GetPresetList( presets);
1095 if( presets.Count() < 1)
1096 {
1097 AudacityMessageBox( XO("No presets to export") );
1098 return;
1099 }
1100
1101 wxString path;
1102 FileDialogWrapper dlg(this,
1103 XO("Select xml file to export presets into"),
1104 gPrefs->Read(wxT("/FileFormats/FFmpegPresetDir")),
1105 wxEmptyString,
1106 FileTypes(),
1107 wxFD_SAVE|wxFD_OVERWRITE_PROMPT);
1108 if (dlg.ShowModal() == wxID_CANCEL) return;
1109 path = dlg.GetPath();
1110 mPresets->ExportPresets(path);
1111}
1112
1115void ExportFFmpegOptions::OnAllFormats(wxCommandEvent& WXUNUSED(event))
1116{
1119 mFormatList->Clear();
1120 mFormatList->Append(mFormatNames);
1121}
1122
1125void ExportFFmpegOptions::OnAllCodecs(wxCommandEvent& WXUNUSED(event))
1126{
1129 mCodecList->Clear();
1130 mCodecList->Append(mCodecNames);
1131}
1132
1141{
1142 wxString *selcdc = nullptr;
1143 wxString* selcdclong = nullptr;
1144
1145 FindSelectedCodec(&selcdc, &selcdclong);
1146
1147 if (selcdc == nullptr)
1148 return false; // unrecognised codec. Treated as OK
1149
1150 auto cdc = mFFmpeg->CreateEncoder(selcdc->ToUTF8());
1151
1152 if (cdc == nullptr)
1153 return false; // unrecognised codec. Treated as OK
1154
1155 wxString* selfmt = nullptr;
1156 wxString* selfmtlong = nullptr;
1157
1158 FindSelectedFormat(&selfmt, &selfmtlong);
1159
1160 if (selfmt == nullptr)
1161 return false; // unrecognised format; Treated as OK
1162
1163 // This is intended to test for illegal combinations.
1164 // However, the list updating now seems to be working correctly
1165 // making it impossible to select illegal combinations
1166 bool bFound = false;
1167 for (int i = 0; CompatibilityList[i].fmt != NULL; i++)
1168 {
1169 if (*selfmt == CompatibilityList[i].fmt)
1170 {
1171 if (CompatibilityList[i].codec == mFFmpeg->GetAudacityCodecID(cdc->GetId()) || (CompatibilityList[i].codec == AUDACITY_AV_CODEC_ID_NONE) ){
1172 bFound = true;
1173 break;
1174 }
1175 }
1176 }
1177
1178 // We can put extra code in here, to disallow combinations
1179 // We could also test for illegal parameters, and deliver
1180 // custom error messages in that case.
1181 // The below would make AAC codec disallowed.
1182 //if( cdc->id == AUDACITY_AV_CODEC_ID_AAC)
1183 // bFound = false;
1184
1185 // Valid combination was found, so no reporting.
1186 if( bFound )
1187 return false;
1188
1190 /* i18n-hint: "codec" is short for a "coder-decoder" algorithm */
1191 XO("Format %s is not compatible with codec %s.")
1192 .Format( *selfmt, *selcdc ),
1193 /* i18n-hint: "codec" is short for a "coder-decoder" algorithm */
1194 XO("Incompatible format and codec"));
1195
1196 return true;
1197}
1198
1199
1200
1202{
1203 int handled = -1;
1204 for (int i = 0; apptable[i].control != 0; i++)
1205 {
1206 if (apptable[i].control != handled)
1207 {
1208 bool codec = false;
1209 bool format = false;
1210 if (apptable[i].codec == AUDACITY_AV_CODEC_ID_NONE)
1211 {
1212 codec = true;
1213 }
1214 else if (
1215 cdc != NULL &&
1216 apptable[i].codec == mFFmpeg->GetAudacityCodecID(cdc->GetId()))
1217 {
1218 codec = true;
1219 }
1220
1221 if (wxString::FromUTF8(apptable[i].format) == wxT("any")) format = true;
1222 else if (selfmt != NULL &&
1223 *selfmt == wxString::FromUTF8(apptable[i].format)) format = true;
1224 if (codec && format)
1225 {
1226 handled = apptable[i].control;
1227 wxWindow *item = FindWindowById(apptable[i].control,this);
1228 if (item != NULL) item->Enable(apptable[i].enable);
1229 }
1230 }
1231 }
1232}
1233
1235{
1236 wxString *selfmt = NULL;
1237 wxString *selfmtlong = NULL;
1238 FindSelectedFormat(&selfmt, &selfmtlong);
1239 if (selfmt == NULL)
1240 {
1241 return;
1242 }
1243
1244 wxString *selcdc = NULL;
1245 wxString *selcdclong = NULL;
1246 FindSelectedCodec(&selcdc, &selcdclong);
1247
1248 auto fmt = mFFmpeg->GuessOutputFormat(selfmt->ToUTF8(),NULL,NULL);
1249 if (fmt == NULL)
1250 {
1251 //This shouldn't really happen
1252 mFormatName->SetLabel(wxString(_("Failed to guess format")));
1253 return;
1254 }
1255 mFormatName->SetLabel(wxString::Format(wxT("%s"), *selfmtlong));
1256
1258
1259 if (selcdc != nullptr)
1260 {
1261 auto cdc = mFFmpeg->CreateEncoder(selcdc->ToUTF8());
1262
1263 if (cdc != nullptr)
1264 {
1265 selcdcid = mFFmpeg->GetAudacityCodecID(cdc->GetId());
1266 }
1267 }
1268 int newselcdc =
1269 FetchCompatibleCodecList(*selfmt, selcdcid);
1270
1271 if (newselcdc >= 0) mCodecList->Select(newselcdc);
1272
1273 std::unique_ptr<AVCodecWrapper> cdc;
1274
1275 if (selcdc != nullptr)
1276 cdc = mFFmpeg->CreateEncoder(selcdc->ToUTF8());
1277
1278 EnableDisableControls(cdc.get(), selfmt);
1279 Layout();
1280 Fit();
1281 return;
1282}
1283
1285{
1286 wxString *selcdc = nullptr;
1287 wxString* selcdclong = nullptr;
1288
1289 FindSelectedCodec(&selcdc, &selcdclong);
1290
1291 if (selcdc == nullptr)
1292 {
1293 return;
1294 }
1295
1296 wxString* selfmt = nullptr;
1297 wxString* selfmtlong = nullptr;
1298
1299 FindSelectedFormat(&selfmt, &selfmtlong);
1300
1301 auto cdc = mFFmpeg->CreateEncoder(selcdc->ToUTF8());
1302 if (cdc == nullptr)
1303 {
1304 //This shouldn't really happen
1305 /* i18n-hint: "codec" is short for a "coder-decoder" algorithm */
1306 mCodecName->SetLabel(wxString(_("Failed to find the codec")));
1307 return;
1308 }
1309
1310 mCodecName->SetLabel(wxString::Format(wxT("[%d] %s"), (int) mFFmpeg->GetAudacityCodecID(cdc->GetId()).value, *selcdclong));
1311
1312 if (selfmt != nullptr)
1313 {
1314 auto fmt = mFFmpeg->GuessOutputFormat(selfmt->ToUTF8(), nullptr, nullptr);
1315 if (fmt == nullptr)
1316 {
1317 selfmt = nullptr;
1318 selfmtlong = nullptr;
1319 }
1320 }
1321
1322 int newselfmt = FetchCompatibleFormatList(
1323 mFFmpeg->GetAudacityCodecID(cdc->GetId()), selfmt);
1324
1325 if (newselfmt >= 0)
1326 mFormatList->Select(newselfmt);
1327
1328 EnableDisableControls(cdc.get(), selfmt);
1329 Layout();
1330 Fit();
1331 return;
1332}
1333
1336void ExportFFmpegOptions::OnFormatList(wxCommandEvent& WXUNUSED(event))
1337{
1339}
1340
1343void ExportFFmpegOptions::OnCodecList(wxCommandEvent& WXUNUSED(event))
1344{
1345 DoOnCodecList();
1346}
1347
1348
1351void ExportFFmpegOptions::OnOK(wxCommandEvent& WXUNUSED(event))
1352{
1354 return;
1355
1356 int selcdc = mCodecList->GetSelection();
1357 int selfmt = mFormatList->GetSelection();
1358 if (selcdc > -1) gPrefs->Write(wxT("/FileFormats/FFmpegCodec"),mCodecList->GetString(selcdc));
1359 if (selfmt > -1) gPrefs->Write(wxT("/FileFormats/FFmpegFormat"),mFormatList->GetString(selfmt));
1360 gPrefs->Flush();
1361
1364
1365 gPrefs->Flush();
1366
1367 EndModal(wxID_OK);
1368
1369 return;
1370}
1371
1372void ExportFFmpegOptions::OnGetURL(wxCommandEvent & WXUNUSED(event))
1373{
1374 HelpSystem::ShowHelp(this, L"Custom_FFmpeg_Export_Options");
1375}
1376
@ AUDACITY_AV_CODEC_ID_GSM_MS
Definition: AVCodecID.h:324
@ AUDACITY_AV_CODEC_ID_IMC
Definition: AVCodecID.h:321
@ AUDACITY_AV_CODEC_ID_QCELP
Definition: AVCodecID.h:318
@ AUDACITY_AV_CODEC_ID_PCM_S16BE
Definition: AVCodecID.h:218
@ AUDACITY_AV_CODEC_ID_ADPCM_G726
Definition: AVCodecID.h:261
@ AUDACITY_AV_CODEC_ID_OPUS
Definition: AVCodecID.h:363
@ AUDACITY_AV_CODEC_ID_ADPCM_IMA_QT
Definition: AVCodecID.h:250
@ AUDACITY_AV_CODEC_ID_QDM2
Definition: AVCodecID.h:313
@ AUDACITY_AV_CODEC_ID_PCM_S24LE
Definition: AVCodecID.h:229
@ AUDACITY_AV_CODEC_ID_ADPCM_YAMAHA
Definition: AVCodecID.h:264
@ AUDACITY_AV_CODEC_ID_AC3
Definition: AVCodecID.h:297
@ AUDACITY_AV_CODEC_ID_MACE3
Definition: AVCodecID.h:303
@ AUDACITY_AV_CODEC_ID_PCM_MULAW
Definition: AVCodecID.h:223
@ AUDACITY_AV_CODEC_ID_PCM_S8
Definition: AVCodecID.h:221
@ AUDACITY_AV_CODEC_ID_VORBIS
Definition: AVCodecID.h:299
@ AUDACITY_AV_CODEC_ID_DVAUDIO
Definition: AVCodecID.h:300
@ AUDACITY_AV_CODEC_ID_PCM_S32BE
Definition: AVCodecID.h:226
@ AUDACITY_AV_CODEC_ID_DTS
Definition: AVCodecID.h:298
@ AUDACITY_AV_CODEC_ID_ALAC
Definition: AVCodecID.h:310
@ AUDACITY_AV_CODEC_ID_PCM_S16LE
Definition: AVCodecID.h:217
@ AUDACITY_AV_CODEC_ID_PCM_S32LE
Definition: AVCodecID.h:225
@ AUDACITY_AV_CODEC_ID_FLAC
Definition: AVCodecID.h:306
@ AUDACITY_AV_CODEC_ID_PCM_ALAW
Definition: AVCodecID.h:224
@ AUDACITY_AV_CODEC_ID_WMAV1
Definition: AVCodecID.h:301
@ AUDACITY_AV_CODEC_ID_NONE
Definition: AVCodecID.h:14
@ AUDACITY_AV_CODEC_ID_ADPCM_SWF
Definition: AVCodecID.h:263
@ AUDACITY_AV_CODEC_ID_VOXWARE
Definition: AVCodecID.h:326
@ AUDACITY_AV_CODEC_ID_NELLYMOSER
Definition: AVCodecID.h:328
@ AUDACITY_AV_CODEC_ID_GSM
Definition: AVCodecID.h:312
@ AUDACITY_AV_CODEC_ID_PCM_U8
Definition: AVCodecID.h:222
@ AUDACITY_AV_CODEC_ID_ROQ_DPCM
Definition: AVCodecID.h:290
@ AUDACITY_AV_CODEC_ID_TRUESPEECH
Definition: AVCodecID.h:315
@ AUDACITY_AV_CODEC_ID_MP2
Definition: AVCodecID.h:294
@ AUDACITY_AV_CODEC_ID_WMAPRO
Definition: AVCodecID.h:332
@ AUDACITY_AV_CODEC_ID_WMAV2
Definition: AVCodecID.h:302
@ AUDACITY_AV_CODEC_ID_AMR_NB
Definition: AVCodecID.h:286
@ AUDACITY_AV_CODEC_ID_MP3
Definition: AVCodecID.h:295
@ AUDACITY_AV_CODEC_ID_PCM_S24BE
Definition: AVCodecID.h:230
@ AUDACITY_AV_CODEC_ID_ATRAC3
Definition: AVCodecID.h:325
@ AUDACITY_AV_CODEC_ID_ADPCM_MS
Definition: AVCodecID.h:256
@ AUDACITY_AV_CODEC_ID_AMR_WB
Definition: AVCodecID.h:287
@ AUDACITY_AV_CODEC_ID_AAC
Definition: AVCodecID.h:296
@ AUDACITY_AV_CODEC_ID_ADPCM_IMA_WAV
Definition: AVCodecID.h:251
@ AUDACITY_AV_CODEC_ID_MACE6
Definition: AVCodecID.h:304
@ AUDACITY_AV_CODEC_ID_WMAVOICE
Definition: AVCodecID.h:331
@ AUDACITY_AV_CODEC_ID_ADPCM_CT
Definition: AVCodecID.h:262
wxT("CloseDown"))
int AudacityMessageBox(const TranslatableString &message, const TranslatableString &caption, long style, wxWindow *parent, int x, int y)
END_EVENT_TABLE()
#define str(a)
EVT_BUTTON(wxID_NO, DependencyDialog::OnNo) EVT_BUTTON(wxID_YES
const TranslatableString name
Definition: Distortion.cpp:76
static const FileNames::FileTypes & FileTypes()
ChoiceSetting AACProfiles
AAC profiles.
@ FMT_M4A
@ FMT_OTHER
@ FMT_AC3
@ FMT_WMA2
@ FMT_AMRNB
FFmpegExportCtrlID
Definition: FFmpegDefines.h:70
#define AV_CANMETA
Definition: FFmpegDefines.h:20
#define AV_VERSION_INT(a, b, c)
Definition: FFmpegTypes.h:77
XO("Cut/Copy/Paste")
XXO("&Cut/Copy/Paste Toolbar")
#define _(s)
Definition: Internat.h:73
IteratorRange< Iterator > make_iterator_range(const Iterator &i1, const Iterator &i2)
Definition: IteratorX.h:210
#define safenew
Definition: MemoryX.h:10
audacity::BasicSettings * gPrefs
Definition: Prefs.cpp:68
EffectReverbSettings preset
Definition: Reverb.cpp:44
@ eIsCreatingFromPrefs
Definition: ShuttleGui.h:46
@ eIsSavingToPrefs
Definition: ShuttleGui.h:47
@ eOkButton
Definition: ShuttleGui.h:609
@ eCancelButton
Definition: ShuttleGui.h:610
@ eHelpButton
Definition: ShuttleGui.h:613
#define S(N)
Definition: ToChars.cpp:64
std::vector< TranslatableString > TranslatableStrings
virtual AVCodecIDFwd GetId() const noexcept=0
Custom FFmpeg export dialog.
void OnExportPresets(wxCommandEvent &event)
void OnSavePreset(wxCommandEvent &event)
void OnImportPresets(wxCommandEvent &event)
void FindSelectedCodec(wxString **name, wxString **longname)
Finds the codec currently selected and returns its name and description.
wxArrayStringEx mCodecNames
void OnDeletePreset(wxCommandEvent &event)
wxArrayString mShownFormatLongNames
void FetchCodecList()
Retrieves codec list from libavcodec.
static CompatibilityEntry CompatibilityList[]
std::unique_ptr< FFmpegPresets > mPresets
int FetchCompatibleFormatList(AudacityAVCodecID id, wxString *selfmt)
void OnCodecList(wxCommandEvent &event)
void PopulateOrExchange(ShuttleGui &S)
void FindSelectedFormat(wxString **name, wxString **longname)
Finds the format currently selected and returns its name and description.
void OnLoadPreset(wxCommandEvent &event)
wxArrayStringEx mFormatNames
wxArrayString mShownCodecLongNames
wxArrayString mShownCodecNames
int FetchCompatibleCodecList(const wxChar *fmt, AudacityAVCodecID id)
wxArrayString mCodecLongNames
void OnFormatList(wxCommandEvent &event)
void OnAllFormats(wxCommandEvent &event)
wxStaticText * mFormatName
void OnOK(wxCommandEvent &event)
ExportFFmpegOptions(wxWindow *parent)
void OnAllCodecs(wxCommandEvent &event)
bool SavePreset(bool bCheckForOverwrite)
void FetchFormatList()
Retrieves format list from libavformat.
static ExposedFormat fmts[]
List of export types.
static ApplicableFor apptable[]
wxArrayString mShownFormatNames
void OnGetURL(wxCommandEvent &event)
wxArrayStringEx mPresetNames
void EnableDisableControls(AVCodecWrapper *cdc, wxString *selfmt)
std::shared_ptr< FFmpegFunctions > mFFmpeg
wxArrayString mFormatLongNames
virtual wxString GetPath() const
virtual int ShowModal()
FILES_API const FileType XMLFiles
Definition: FileNames.h:73
std::vector< FileType > FileTypes
Definition: FileNames.h:75
FILES_API const FileType AllFiles
Definition: FileNames.h:70
Abstract base class used in importing a file.
static void ShowHelp(wxWindow *parent, const FilePath &localFileName, const URLString &remoteURL, bool bModal=false, bool alwaysDefaultBrowser=false)
Definition: HelpSystem.cpp:231
Specialization of Setting for int.
Definition: Prefs.h:356
Derived from ShuttleGuiBase, an Audacity specific class for shuttling data to and from GUI.
Definition: ShuttleGui.h:640
An alternative to using wxWindowAccessible, which in wxWidgets 3.1.1 contained GetParent() which was ...
virtual bool Flush() noexcept=0
virtual bool Write(const wxString &key, bool value)=0
virtual bool Read(const wxString &key, bool *value) const =0
const TranslatableStrings PredictionOrderMethodNames
Prediction order method - names.
std::string ToUTF8(const std::wstring &wstr)
Entry for the Applicability table.
int control
control ID
Describes format-codec compatibility.
const wxChar * fmt
format, recognizable by guess_format()
AudacityAVCodecID codec
codec ID
Describes export type.
static std::shared_ptr< FFmpegFunctions > Load(bool fromUserPathOnly=false)