1 /**********************************************************************
2 
3 Audacity: A Digital Audio Editor
4 
5 ExportFFmpegDialogs.h
6 
7 LRN
8 
9 **********************************************************************/
10 
11 #if !defined(__EXPORT_FFMPEG_DIALOGS_H__)
12 #define __EXPORT_FFMPEG_DIALOGS_H__
13 
14 #if defined(USE_FFMPEG)
15 
16 #include "../FFmpeg.h"
17 #include "FFmpegFunctions.h"
18 
19 #include "XMLFileReader.h"
20 #include "FileNames.h"
21 
22 #include <unordered_map>
23 #include "Identifier.h"
24 
25 class wxArrayStringEx;
26 
27 class wxArrayString;
28 class wxCheckBox;
29 class wxStaticText;
30 class wxTextCtrl;
31 
32 /// Identifiers for pre-set export types.
33 enum FFmpegExposedFormat
34 {
35    FMT_M4A,
36    FMT_AC3,
37    FMT_AMRNB,
38    FMT_OPUS,
39    FMT_WMA2,
40    FMT_OTHER,
41    FMT_LAST
42 };
43 
44 #define AV_CANMETA (AV_VERSION_INT(255, 255, 255))
45 
46 /// Describes export type
47 struct ExposedFormat
48 {
49    FFmpegExposedFormat fmtid; //!< one of the FFmpegExposedFormat
50    const wxChar *name;        //!< format name (internal, should be unique; if not - export dialog may show unusual behaviour)
51    const FileExtension extension;   //!< default extension for this format. More extensions may be added later via AddExtension.
52    const wxChar *shortname;   //!< used to guess the format
53    unsigned maxchannels;      //!< how many channels this format could handle
54    const int canmetadata;           //!< !=0 if format supports metadata, AV_CANMETA any avformat version, otherwise version support added
55    bool canutf8;              //!< true if format supports metadata in UTF-8, false otherwise
56    const TranslatableString description; //!< format description (will be shown in export dialog)
57    AudacityAVCodecID codecid;         //!< codec ID (see libavcodec/avcodec.h)
58    bool compiledIn;           //!< support for this codec/format is compiled in (checked at runtime)
59 };
60 
61 
62 /// Describes format-codec compatibility
63 struct CompatibilityEntry
64 {
65    const wxChar *fmt; //!< format, recognizable by guess_format()
66    AudacityAVCodecID codec; //!< codec ID
67 };
68 
69 
70 /// AC3 export options dialog
71 class ExportFFmpegAC3Options final : public wxPanelWrapper
72 {
73 public:
74 
75    ExportFFmpegAC3Options(wxWindow *parent, int format);
76    virtual ~ExportFFmpegAC3Options();
77 
78    void PopulateOrExchange(ShuttleGui & S);
79    bool TransferDataToWindow() override;
80    bool TransferDataFromWindow() override;
81 
82    /// Sample Rates supported by AC3 encoder (must end with zero-element)
83    /// It is not used in dialog anymore, but will be required later
84    static const int iAC3SampleRates[];
85 
86 private:
87 
88    wxChoice *mBitRateChoice;
89    int mBitRateFromChoice;
90 };
91 
92 class ExportFFmpegAACOptions final : public wxPanelWrapper
93 {
94 public:
95 
96    ExportFFmpegAACOptions(wxWindow *parent, int format);
97    virtual ~ExportFFmpegAACOptions();
98 
99    void PopulateOrExchange(ShuttleGui & S);
100    bool TransferDataToWindow() override;
101    bool TransferDataFromWindow() override;
102 };
103 
104 class ExportFFmpegAMRNBOptions final : public wxPanelWrapper
105 {
106 public:
107 
108    ExportFFmpegAMRNBOptions(wxWindow *parent, int format);
109    virtual ~ExportFFmpegAMRNBOptions();
110 
111    void PopulateOrExchange(ShuttleGui & S);
112    bool TransferDataToWindow() override;
113    bool TransferDataFromWindow() override;
114 
115 private:
116 
117    wxChoice *mBitRateChoice;
118    int mBitRateFromChoice;
119 };
120 
121 class ExportFFmpegOPUSOptions final : public wxPanelWrapper
122 {
123 public:
124 
125    ExportFFmpegOPUSOptions(wxWindow *parent, int format);
126    ~ExportFFmpegOPUSOptions();
127 
128    void PopulateOrExchange(ShuttleGui & S);
129    bool TransferDataToWindow() override;
130    bool TransferDataFromWindow() override;
131 
132    static const int iOPUSSampleRates[];
133 
134 private:
135 
136    wxSlider *mBitRateSlider;
137    int mBitRateFromSlider;
138 
139    wxChoice *mVbrChoice;
140    int mVbrFromChoice;
141 
142    wxSlider *mComplexitySlider;
143    int mComplexityFromSlider;
144 
145    wxChoice *mFramesizeChoice;
146    int mFramesizeFromChoice;
147 
148    wxChoice *mApplicationChoice;
149    int mApplicationFromChoice;
150 
151    wxChoice *mCuttoffChoice;
152    int mCutoffFromChoice;
153 };
154 
155 class ExportFFmpegWMAOptions final : public wxPanelWrapper
156 {
157 public:
158 
159    ExportFFmpegWMAOptions(wxWindow *parent, int format);
160    ~ExportFFmpegWMAOptions();
161 
162    void PopulateOrExchange(ShuttleGui & S);
163    bool TransferDataToWindow() override;
164    bool TransferDataFromWindow() override;
165 
166    static const int iWMASampleRates[];
167 
168 private:
169 
170    wxChoice *mBitRateChoice;
171    int mBitRateFromChoice;
172 };
173 
174 class ExportFFmpegCustomOptions final : public wxPanelWrapper
175 {
176 public:
177 
178    ExportFFmpegCustomOptions(wxWindow *parent, int format);
179    ~ExportFFmpegCustomOptions();
180 
181    void PopulateOrExchange(ShuttleGui & S);
182    bool TransferDataToWindow() override;
183    bool TransferDataFromWindow() override;
184 
185    void OnOpen(wxCommandEvent & evt);
186 
187 private:
188    wxTextCtrl *mFormat;
189    wxTextCtrl *mCodec;
190 
191    DECLARE_EVENT_TABLE()
192 };
193 
194 /// Entry for the Applicability table
195 struct ApplicableFor
196 {
197    bool                 enable;  //!< true if this control should be enabled, false otherwise
198    int                  control; //!< control ID
199    AudacityAVCodecID codec;      //!< Codec ID
200    const char          *format;  //!< Format short name
201 };
202 
203 class FFmpegPresets;
204 
205 /// Custom FFmpeg export dialog
206 class ExportFFmpegOptions final : public wxDialogWrapper
207 {
208 public:
209 
210    ExportFFmpegOptions(wxWindow *parent);
211    ~ExportFFmpegOptions();
212    void PopulateOrExchange(ShuttleGui & S);
213    void OnOK(wxCommandEvent& event);
214    void OnGetURL(wxCommandEvent& event);
215    void OnFormatList(wxCommandEvent& event);
216    void DoOnFormatList();
217    void OnCodecList(wxCommandEvent& event);
218    void DoOnCodecList();
219    void OnAllFormats(wxCommandEvent& event);
220    void OnAllCodecs(wxCommandEvent& event);
221    void OnSavePreset(wxCommandEvent& event);
222    void OnLoadPreset(wxCommandEvent& event);
223    void OnDeletePreset(wxCommandEvent& event);
224    void OnImportPresets(wxCommandEvent& event);
225    void OnExportPresets(wxCommandEvent& event);
226    bool SavePreset( bool bCheckForOverwrite);
227 
228 
229    // Static tables
230    static CompatibilityEntry CompatibilityList[];
231    static ExposedFormat fmts[];
232    static const int iAACSampleRates[];
233    static ApplicableFor apptable[];
234 
235 private:
236 
237    wxArrayString mShownFormatNames;
238    wxArrayString mShownFormatLongNames;
239    wxArrayString mShownCodecNames;
240    wxArrayString mShownCodecLongNames;
241    wxArrayStringEx mFormatNames;
242    wxArrayString mFormatLongNames;
243    wxArrayStringEx mCodecNames;
244    wxArrayString mCodecLongNames;
245 
246    wxListBox *mFormatList;
247    wxListBox *mCodecList;
248 
249    wxStaticText *mFormatName;
250    wxStaticText *mCodecName;
251 
252    wxComboBox *mPresetCombo;
253 
254    int mBitRateFromChoice;
255    int mSampleRateFromChoice;
256 
257    std::unique_ptr<FFmpegPresets> mPresets;
258 
259    wxArrayStringEx mPresetNames;
260 
261    std::shared_ptr<FFmpegFunctions> mFFmpeg;
262 
263    /// Finds the format currently selected and returns its name and description
264    void FindSelectedFormat(wxString **name, wxString **longname);
265 
266    /// Finds the codec currently selected and returns its name and description
267    void FindSelectedCodec(wxString **name, wxString **longname);
268 
269    /// Retrieves format list from libavformat
270    void FetchFormatList();
271 
272    /// Retrieves a list of formats compatible to codec
273    ///\param id Codec ID
274    ///\param selfmt format selected at the moment
275    ///\return index of the selfmt in NEW format list or -1 if it is not in the list
276    int FetchCompatibleFormatList(AudacityAVCodecID id, wxString* selfmt);
277 
278    /// Retrieves codec list from libavcodec
279    void FetchCodecList();
280 
281    /// Retrieves a list of codecs compatible to format
282    ///\param fmt Format short name
283    ///\param id id of the codec selected at the moment
284    ///\return index of the id in NEW codec list or -1 if it is not in the list
285    int FetchCompatibleCodecList(const wxChar* fmt, AudacityAVCodecID id);
286 
287    /// Retrieves list of presets from configuration file
288    void FetchPresetList();
289 
290    bool ReportIfBadCombination();
291 
292 
293    // Enables/disables controls based on format/codec combination,
294    // leaving only relevant controls enabled.
295    // Hiding the controls may have been a better idea,
296    // but it's hard to hide their text labels too
297    void EnableDisableControls(AVCodecWrapper *cdc, wxString *selfmt);
298    DECLARE_EVENT_TABLE()
299 };
300 
301 //----------------------------------------------------------------------------
302 // FFmpegPresets
303 //----------------------------------------------------------------------------
304 
305 class FFmpegPreset
306 {
307 public:
308    FFmpegPreset();
309    ~FFmpegPreset();
310 
311    wxString mPresetName;
312    wxArrayString mControlState;
313 
314 };
315 
316 using FFmpegPresetMap = std::unordered_map<wxString, FFmpegPreset>;
317 
318 class FFmpegPresets : XMLTagHandler
319 {
320 public:
321    FFmpegPresets();
322    ~FFmpegPresets();
323 
324    void GetPresetList(wxArrayString &list);
325    void LoadPreset(ExportFFmpegOptions *parent, wxString &name);
326    bool SavePreset(ExportFFmpegOptions *parent, wxString &name);
327    void DeletePreset(wxString &name);
328    bool OverwriteIsOk( wxString &name );
329    FFmpegPreset *FindPreset(wxString &name);
330 
331    void ImportPresets(wxString &filename);
332    void ExportPresets(wxString &filename);
333 
334    bool HandleXMLTag(const std::string_view& tag, const AttributesList &attrs) override;
335    XMLTagHandler *HandleXMLChild(const std::string_view& tag) override;
336    void WriteXMLHeader(XMLWriter &xmlFile) const;
337    void WriteXML(XMLWriter &xmlFile) const;
338 
339 private:
340 
341    FFmpegPresetMap mPresets;
342    FFmpegPreset *mPreset; // valid during XML parsing only
343    bool mAbortImport; // tells importer to ignore the rest of the import
344 };
345 
346 #endif
347 
348 #endif //__EXPORT_FFMPEG_DIALOGS_H__
349