diff --git a/src/FFmpeg.cpp b/src/FFmpeg.cpp index 6202b42b7..046e8c070 100644 --- a/src/FFmpeg.cpp +++ b/src/FFmpeg.cpp @@ -71,8 +71,8 @@ bool LoadFFmpeg(bool showerror) PickFFmpegLibs(); if (FFmpegLibsInst->ValidLibsLoaded()) { - DropFFmpegLibs(); - return true; + DropFFmpegLibs(); + return true; } if (!FFmpegLibsInst->LoadLibs(NULL,showerror)) { @@ -155,7 +155,7 @@ void av_log_wx_callback(void* ptr, int level, const char* fmt, va_list vl) } #ifdef EXPERIMENTAL_OD_FFMPEG //if the decoding happens thru OD then this gets called from a non main thread, which means wxLogDebug -//will crash. +//will crash. //TODO:find some workaround for the log. perhaps use ODManager as a bridge. for now just print if(!wxThread::IsMain()) printf("%s: %s\n",(char*)cpt.char_str(),(char*)printstring.char_str()); @@ -189,16 +189,16 @@ static int64_t ufile_seek(void *opaque, int64_t pos, int whence) switch (whence & ~AVSEEK_FORCE) { case (SEEK_SET): - mode = wxFromStart; - break; + mode = wxFromStart; + break; case (SEEK_CUR): - mode = wxFromCurrent; - break; + mode = wxFromCurrent; + break; case (SEEK_END): - mode = wxFromEnd; - break; + mode = wxFromEnd; + break; case (AVSEEK_SIZE): - return ((wxFile *) opaque)->Length(); + return ((wxFile *) opaque)->Length(); } return ((wxFile *) opaque)->Seek(pos, mode); @@ -213,9 +213,9 @@ int ufile_close(AVIOContext *pb) delete f; } - return 0; + return 0; } - + // Open a file with a (possibly) Unicode filename int ufile_fopen(AVIOContext **s, const wxString & name, int flags) { @@ -276,7 +276,7 @@ int ufile_fopen_input(AVFormatContext **ic_ptr, wxString & name) *ic_ptr = avformat_alloc_context(); (*ic_ptr)->pb = pb; - + // And finally, attempt to associate an input stream with the file err = avformat_open_input(ic_ptr, filename, NULL, NULL); if (err) { @@ -335,7 +335,7 @@ streamContext *import_ffmpeg_read_next_frame(AVFormatContext* formatContext, int import_ffmpeg_decode_frame(streamContext *sc, bool flushing) { - int nBytesDecoded; + int nBytesDecoded; wxUint8 *pDecode = sc->m_pktDataPtr; int nDecodeSiz = sc->m_pktRemainingSiz; @@ -363,13 +363,13 @@ int import_ffmpeg_decode_frame(streamContext *sc, bool flushing) AVFrame *frame = av_frame_alloc(); int got_output = 0; - + nBytesDecoded = avcodec_decode_audio4(sc->m_codecCtx, frame, // out &got_output, // out &avpkt); // in - + if (nBytesDecoded < 0) { // Decoding failed. Don't stop. @@ -404,15 +404,15 @@ int import_ffmpeg_decode_frame(streamContext *sc, bool flushing) } } if (frame->data[1]) { - for (int i = 0; i<frame->nb_samples; i++) { - for (int ch = 0; ch<channels; ch++) { - memcpy(sc->m_decodedAudioSamples + sc->m_samplesize * (ch + channels*i), - frame->extended_data[ch] + sc->m_samplesize*i, - sc->m_samplesize); - } - } + for (int i = 0; i<frame->nb_samples; i++) { + for (int ch = 0; ch<channels; ch++) { + memcpy(sc->m_decodedAudioSamples + sc->m_samplesize * (ch + channels*i), + frame->extended_data[ch] + sc->m_samplesize*i, + sc->m_samplesize); + } + } } else { - memcpy(sc->m_decodedAudioSamples, frame->data[0], newsize); + memcpy(sc->m_decodedAudioSamples, frame->data[0], newsize); } av_frame_free(&frame); @@ -518,7 +518,7 @@ public: "Where would I find the file '%s'?" instead if you want. */ question.Printf(_("Where is '%s'?"), mName.c_str()); - wxString path = FileSelector(question, + wxString path = FileSelector(question, mLibPath.GetPath(), mLibPath.GetName(), wxT(""), @@ -605,7 +605,7 @@ bool FFmpegLibs::FindLibs(wxWindow *parent) else { path = GetLibAVFormatPath(); name = GetLibAVFormatName(); - wxLogMessage(wxT("mLibAVFormatPath is empty, starting with path '%s', name '%s'."), + wxLogMessage(wxT("mLibAVFormatPath is empty, starting with path '%s', name '%s'."), path.c_str(), name.c_str()); } @@ -663,7 +663,7 @@ bool FFmpegLibs::LoadLibs(wxWindow * WXUNUSED(parent), bool showerr) mLibAVFormatPath = path; } } - + #if defined(__WXMAC__) // If not successful, try loading it from legacy path if (!mLibsLoaded && !GetLibAVFormatPath().IsEmpty()) { @@ -697,16 +697,16 @@ bool FFmpegLibs::LoadLibs(wxWindow * WXUNUSED(parent), bool showerr) gPrefs->Read(wxT("/FFmpeg/NotFoundDontShow"),&dontShowDlg,0); if ((dontShowDlg == 0) && (showerr)) { - dlg = new FFmpegNotFoundDialog(NULL); - dlg->ShowModal(); - delete dlg; + dlg = new FFmpegNotFoundDialog(NULL); + dlg->ShowModal(); + delete dlg; } } */ // Oh well, just give up if (!ValidLibsLoaded()) { wxString msg = _("Failed to find compatible FFmpeg libraries."); - if (showerr) + if (showerr) wxMessageBox(msg); wxLogError(msg); return false; @@ -791,8 +791,8 @@ bool FFmpegLibs::InitLibs(wxString libpath_format, bool WXUNUSED(showerr)) if (actual.GetFullPath().IsSameAs(name.GetFullPath())) { actual = FileNames::PathFromAddr(avformat->GetSymbol(wxT("avcodec_version"))); if (actual.GetFullPath().IsSameAs(name.GetFullPath())) { - util = avformat; - codec = avformat; + util = avformat; + codec = avformat; } } @@ -941,7 +941,7 @@ bool FFmpegLibs::InitLibs(wxString libpath_format, bool WXUNUSED(showerr)) //FFmpeg initialization avcodec_register_all(); av_register_all(); - + wxLogMessage(wxT("Retrieving FFmpeg library version numbers:")); int avfver = avformat_version(); int avcver = avcodec_version(); @@ -950,14 +950,14 @@ bool FFmpegLibs::InitLibs(wxString libpath_format, bool WXUNUSED(showerr)) mAVFormatVersion = wxString::Format(wxT("%d.%d.%d"),avfver >> 16 & 0xFF, avfver >> 8 & 0xFF, avfver & 0xFF); mAVUtilVersion = wxString::Format(wxT("%d.%d.%d"),avuver >> 16 & 0xFF, avuver >> 8 & 0xFF, avuver & 0xFF); - wxLogMessage(wxT(" AVCodec version 0x%06x - %s (built against 0x%06x - %s)"), - avcver, mAVCodecVersion.c_str(), LIBAVCODEC_VERSION_INT, + wxLogMessage(wxT(" AVCodec version 0x%06x - %s (built against 0x%06x - %s)"), + avcver, mAVCodecVersion.c_str(), LIBAVCODEC_VERSION_INT, wxString::FromUTF8(AV_STRINGIFY(LIBAVCODEC_VERSION)).c_str()); - wxLogMessage(wxT(" AVFormat version 0x%06x - %s (built against 0x%06x - %s)"), - avfver, mAVFormatVersion.c_str(), LIBAVFORMAT_VERSION_INT, + wxLogMessage(wxT(" AVFormat version 0x%06x - %s (built against 0x%06x - %s)"), + avfver, mAVFormatVersion.c_str(), LIBAVFORMAT_VERSION_INT, wxString::FromUTF8(AV_STRINGIFY(LIBAVFORMAT_VERSION)).c_str()); - wxLogMessage(wxT(" AVUtil version 0x%06x - %s (built against 0x%06x - %s)"), - avuver,mAVUtilVersion.c_str(), LIBAVUTIL_VERSION_INT, + wxLogMessage(wxT(" AVUtil version 0x%06x - %s (built against 0x%06x - %s)"), + avuver,mAVUtilVersion.c_str(), LIBAVUTIL_VERSION_INT, wxString::FromUTF8(AV_STRINGIFY(LIBAVUTIL_VERSION)).c_str()); int avcverdiff = (avcver >> 16 & 0xFF) - int(LIBAVCODEC_VERSION_MAJOR); diff --git a/src/export/ExportFFmpeg.cpp b/src/export/ExportFFmpeg.cpp index 7e8471bdb..28386004f 100644 --- a/src/export/ExportFFmpeg.cpp +++ b/src/export/ExportFFmpeg.cpp @@ -12,8 +12,8 @@ ******************************************************************//** \class ExportFFmpeg -\brief Controlling class for FFmpeg exporting. Creates the options -dialog of the appropriate type, adds tags and invokes the export +\brief Controlling class for FFmpeg exporting. Creates the options +dialog of the appropriate type, adds tags and invokes the export function. *//*******************************************************************/ @@ -97,14 +97,14 @@ public: /// Format intialization bool Init(const char *shortname, AudacityProject *project, Tags *metadata, int subformat); - + /// Codec intialization bool InitCodecs(AudacityProject *project); /// Writes metadata bool AddTags(Tags *metadata); - /// Sets individual metadata values + /// Sets individual metadata values void SetMetadata(Tags *tags, const char *name, const wxChar *tag); /// Encodes audio @@ -177,7 +177,7 @@ ExportFFmpeg::ExportFFmpeg() #define MAX_AUDIO_PACKET_SIZE (128 * 1024) mEncAudioFifoOutBuf = NULL; // buffer to read _out_ of the FIFO into mEncAudioFifoOutBufSiz = 0; - + #if LIBAVUTIL_VERSION_INT < AV_VERSION_INT(50, 0, 0) mEncAudioFifo = &mEncAudioFifoBuffer; #endif @@ -282,7 +282,7 @@ bool ExportFFmpeg::Init(const char *shortname, AudacityProject *project, Tags *m // Initialise the output format context. mEncFormatCtx->oformat = mEncFormatDesc; memcpy(mEncFormatCtx->filename, OSINPUT(mName), strlen(OSINPUT(mName))+1); - + // At the moment Audacity can export only one audio stream #if !defined(DISABLE_DYNAMIC_LOADING_FFMPEG) || (LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(53, 10, 0)) if ((mEncAudioStream = av_new_stream(mEncFormatCtx, 1)) == NULL) @@ -341,9 +341,9 @@ bool ExportFFmpeg::CheckSampleRate(int rate, int lowrate, int highrate, const in static int set_dict_int(AVDictionary **dict, const char *key, int val) { - char val_str[256]; - snprintf(val_str, sizeof(val_str), "%d", val); - return av_dict_set(dict, key, val_str, 0); + char val_str[256]; + snprintf(val_str, sizeof(val_str), "%d", val); + return av_dict_set(dict, key, val_str, 0); } bool ExportFFmpeg::InitCodecs(AudacityProject *project) @@ -353,7 +353,7 @@ bool ExportFFmpeg::InitCodecs(AudacityProject *project) // Configure the audio stream's codec context. mEncAudioCodecCtx = mEncAudioStream->codec; - + mEncAudioCodecCtx->codec_id = ExportFFmpegOptions::fmts[mSubFormat].codecid; mEncAudioCodecCtx->codec_type = AVMEDIA_TYPE_AUDIO; mEncAudioCodecCtx->codec_tag = av_codec_get_tag((const AVCodecTag **)mEncFormatCtx->oformat->codec_tag,mEncAudioCodecCtx->codec_id); @@ -404,7 +404,7 @@ bool ExportFFmpeg::InitCodecs(AudacityProject *project) mEncAudioCodecCtx->cutoff = gPrefs->Read(wxT("/FileFormats/FFmpegCutOff"),(long)0); mEncAudioCodecCtx->flags2 = 0; if (gPrefs->Read(wxT("/FileFormats/FFmpegBitReservoir"),true)) - av_dict_set(&options, "reservoir", "1", 0); + av_dict_set(&options, "reservoir", "1", 0); if (gPrefs->Read(wxT("/FileFormats/FFmpegVariableBlockLen"),true)) mEncAudioCodecCtx->flags2 |= 0x0004; //WMA only? #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(53, 0, 0) mEncAudioCodecCtx->use_lpc = gPrefs->Read(wxT("/FileFormats/FFmpegUseLPC"),true); @@ -497,12 +497,12 @@ bool ExportFFmpeg::InitCodecs(AudacityProject *project) default_frame_size = mEncAudioCodecCtx->frame_size; if (default_frame_size == 0) - default_frame_size = 1024; // arbitrary non zero value; - + default_frame_size = 1024; // arbitrary non zero value; + wxLogDebug(wxT("FFmpeg : Audio Output Codec Frame Size: %d samples."), mEncAudioCodecCtx->frame_size); // The encoder may require a minimum number of raw audio samples for each encoding but we can't - // guarantee we'll get this minimum each time an audio frame is decoded from the input file so + // guarantee we'll get this minimum each time an audio frame is decoded from the input file so // we use a FIFO to store up incoming raw samples until we have enough for one call to the codec. #if LIBAVUTIL_VERSION_INT > AV_VERSION_INT(49, 15, 0) mEncAudioFifo = av_fifo_alloc(1024); @@ -614,7 +614,7 @@ bool ExportFFmpeg::Finalize() } // Flush the audio FIFO first if necessary. It won't contain a _full_ audio frame because - // if it did we'd have pulled it from the FIFO during the last encodeAudioFrame() call - + // if it did we'd have pulled it from the FIFO during the last encodeAudioFrame() call - // the encoder must support short/incomplete frames for this to work. if (nFifoBytes > 0) { @@ -640,7 +640,7 @@ bool ExportFFmpeg::Finalize() if (codec->capabilities & (CODEC_CAP_SMALL_LAST_FRAME|CODEC_CAP_VARIABLE_FRAME_SIZE)) frame_size = nFifoBytes / (mEncAudioCodecCtx->channels * sizeof(int16_t)); - wxLogDebug(wxT("FFmpeg : Audio FIFO still contains %d bytes, writing %d sample frame ..."), + wxLogDebug(wxT("FFmpeg : Audio FIFO still contains %d bytes, writing %d sample frame ..."), nFifoBytes, frame_size); // Pull the bytes out from the FIFO and feed them to the encoder. @@ -659,7 +659,7 @@ bool ExportFFmpeg::Finalize() if (nEncodedBytes <= 0) nEncodedBytes = encode_audio(mEncAudioCodecCtx, &pkt, NULL, 0); - if (nEncodedBytes <= 0) + if (nEncodedBytes <= 0) break; pkt.stream_index = mEncAudioStream->index; @@ -790,9 +790,9 @@ int ExportFFmpeg::Export(AudacityProject *project, wxLogError(wxT("Attempted to export %d channels, but max. channels = %d"),channels,ExportFFmpegOptions::fmts[mSubFormat].maxchannels); wxMessageBox( wxString::Format( - _("Attempted to export %d channels, but maximum number of channels for selected output format is %d"), - channels, - ExportFFmpegOptions::fmts[mSubFormat].maxchannels), + _("Attempted to export %d channels, but maximum number of channels for selected output format is %d"), + channels, + ExportFFmpegOptions::fmts[mSubFormat].maxchannels), _("Error")); return false; } @@ -801,7 +801,7 @@ int ExportFFmpeg::Export(AudacityProject *project, bool ret = true; if (mSubFormat >= FMT_LAST) return false; - + wxString shortname(ExportFFmpegOptions::fmts[mSubFormat].shortname); if (mSubFormat == FMT_OTHER) shortname = gPrefs->Read(wxT("/FileFormats/FFmpegFormat"),wxT("matroska")); diff --git a/src/export/ExportFFmpegDialogs.cpp b/src/export/ExportFFmpegDialogs.cpp index f1d5272aa..0130837ec 100644 --- a/src/export/ExportFFmpegDialogs.cpp +++ b/src/export/ExportFFmpegDialogs.cpp @@ -163,8 +163,8 @@ ExportFFmpegAC3Options::ExportFFmpegAC3Options(wxWindow *parent) PopulateOrExchange(S); } -/// -/// +/// +/// void ExportFFmpegAC3Options::PopulateOrExchange(ShuttleGui & S) { S.StartHorizontalLay(wxEXPAND, 0); @@ -173,7 +173,7 @@ void ExportFFmpegAC3Options::PopulateOrExchange(ShuttleGui & S) { S.StartTwoColumn(); { - S.TieChoice(_("Bit Rate:"), wxT("/FileFormats/AC3BitRate"), + S.TieChoice(_("Bit Rate:"), wxT("/FileFormats/AC3BitRate"), 160000, mBitRateNames, mBitRateLabels); } S.EndTwoColumn(); @@ -192,8 +192,8 @@ void ExportFFmpegAC3Options::PopulateOrExchange(ShuttleGui & S) return; } -/// -/// +/// +/// void ExportFFmpegAC3Options::OnOK(wxCommandEvent& WXUNUSED(event)) { ShuttleGui S(this, eIsSavingToPrefs); @@ -221,8 +221,8 @@ ExportFFmpegAACOptions::ExportFFmpegAACOptions(wxWindow *parent) PopulateOrExchange(S); } -/// -/// +/// +/// void ExportFFmpegAACOptions::PopulateOrExchange(ShuttleGui & S) { S.StartStatic(_("AAC Export Setup"), 1); @@ -245,8 +245,8 @@ void ExportFFmpegAACOptions::PopulateOrExchange(ShuttleGui & S) return; } -/// -/// +/// +/// void ExportFFmpegAACOptions::OnOK(wxCommandEvent& WXUNUSED(event)) { ShuttleGui S(this, eIsSavingToPrefs); @@ -286,8 +286,8 @@ ExportFFmpegAMRNBOptions::ExportFFmpegAMRNBOptions(wxWindow *parent) PopulateOrExchange(S); } -/// -/// +/// +/// void ExportFFmpegAMRNBOptions::PopulateOrExchange(ShuttleGui & S) { S.StartHorizontalLay(wxEXPAND, 0); @@ -296,7 +296,7 @@ void ExportFFmpegAMRNBOptions::PopulateOrExchange(ShuttleGui & S) { S.StartTwoColumn(); { - S.TieChoice(_("Bit Rate:"), wxT("/FileFormats/AMRNBBitRate"), + S.TieChoice(_("Bit Rate:"), wxT("/FileFormats/AMRNBBitRate"), 12200, mBitRateNames, mBitRateLabels); } S.EndTwoColumn(); @@ -315,8 +315,8 @@ void ExportFFmpegAMRNBOptions::PopulateOrExchange(ShuttleGui & S) return; } -/// -/// +/// +/// void ExportFFmpegAMRNBOptions::OnOK(wxCommandEvent& WXUNUSED(event)) { ShuttleGui S(this, eIsSavingToPrefs); @@ -358,8 +358,8 @@ ExportFFmpegWMAOptions::ExportFFmpegWMAOptions(wxWindow *parent) PopulateOrExchange(S); } -/// -/// +/// +/// void ExportFFmpegWMAOptions::PopulateOrExchange(ShuttleGui & S) { S.StartHorizontalLay(wxEXPAND, 0); @@ -368,7 +368,7 @@ void ExportFFmpegWMAOptions::PopulateOrExchange(ShuttleGui & S) { S.StartTwoColumn(); { - S.TieChoice(_("Bit Rate:"), wxT("/FileFormats/WMABitRate"), + S.TieChoice(_("Bit Rate:"), wxT("/FileFormats/WMABitRate"), 96000, mBitRateNames, mBitRateLabels); } S.EndTwoColumn(); @@ -387,8 +387,8 @@ void ExportFFmpegWMAOptions::PopulateOrExchange(ShuttleGui & S) return; } -/// -/// +/// +/// void ExportFFmpegWMAOptions::OnOK(wxCommandEvent& WXUNUSED(event)) { ShuttleGui S(this, eIsSavingToPrefs); @@ -458,7 +458,7 @@ wxArrayString *FFmpegPresets::GetPresetList() { FFmpegPreset *preset = *iter; list->Add(*preset->mPresetName); - } + } return list; } @@ -542,7 +542,7 @@ void FFmpegPresets::SavePreset(ExportFFmpegOptions *parent, wxString &name) // Spin control case FEBitrateID: case FEQualityID: - case FESampleRateID: + case FESampleRateID: case FECutoffID: case FEFrameSizeID: case FEBufSizeID: @@ -625,7 +625,7 @@ void FFmpegPresets::LoadPreset(ExportFFmpegOptions *parent, wxString &name) case FELPCCoeffsID: case FEMinPredID: case FEMaxPredID: - case FEMinPartOrderID: + case FEMinPartOrderID: case FEMaxPartOrderID: case FEMuxRateID: case FEPacketSizeID: @@ -793,7 +793,7 @@ END_EVENT_TABLE() /// Format-codec compatibility list /// Must end with NULL entry -CompatibilityEntry ExportFFmpegOptions::CompatibilityList[] = +CompatibilityEntry ExportFFmpegOptions::CompatibilityList[] = { { wxT("adts"), CODEC_ID_AAC }, @@ -1137,7 +1137,7 @@ const int ExportFFmpegOptions::iAACSampleRates[] = { 7350, 8000, 11025, 12000, 1 /// "any" - any format /// CODEC_ID_NONE - any codec /// This list must end with {FALSE,FFmpegExportCtrlID(0),CODEC_ID_NONE,NULL} -ApplicableFor ExportFFmpegOptions::apptable[] = +ApplicableFor ExportFFmpegOptions::apptable[] = { {TRUE,FEQualityID,CODEC_ID_AAC,"any"}, {TRUE,FEQualityID,CODEC_ID_MP3,"any"}, @@ -1309,157 +1309,156 @@ void ExportFFmpegOptions::FetchCodecList() 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(wxT("")); - S.Id(FECodecLabelID).AddFixedText(_("Codec:")); - mCodecName = S.Id(FECodecNameID).AddVariableText(wxT("")); - } - 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.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(wxT("")); + S.Id(FECodecLabelID).AddFixedText(_("Codec:")); + mCodecName = S.Id(FECodecNameID).AddVariableText(wxT("")); + } + 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(wxEmptyString, wxT("/FileFormats/FFmpegBitReservoir"), true); + S.AddSpace( 20,0 ); + S.AddVariableText(_("Bit Reservoir")); + S.Id(FEBitReservoirID).TieCheckBox(wxEmptyString, wxT("/FileFormats/FFmpegBitReservoir"), true); - S.AddSpace( 20,0 ); - S.AddVariableText(_("VBL")); - S.Id(FEVariableBlockLenID).TieCheckBox(wxEmptyString, 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")); + S.AddSpace( 20,0 ); + S.AddVariableText(_("VBL")); + S.Id(FEVariableBlockLenID).TieCheckBox(wxEmptyString, 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")); + 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)")); + 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")); + 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")); + 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")); + 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)")); + } + 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")); + 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")); + 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")); + 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)")); + 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)")); + 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")); + 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/FFmpegMaxPredOrder"), -1, 8, -1); - mMaxPartitionOrderSpin->SetToolTip(_("Maximal partition order\nOptional\n-1 - default\nmin - 0\nmax - 8")); + mMaxPartitionOrderSpin = S.Id(FEMaxPartOrderID).TieSpinCtrl(_("Max. PtO"), wxT("/FileFormats/FFmpegMaxPredOrder"), -1, 8, -1); + mMaxPartitionOrderSpin->SetToolTip(_("Maximal partition order\nOptional\n-1 - default\nmin - 0\nmax - 8")); - S.AddVariableText(_("Use LPC")); - S.Id(FEUseLPCID).TieCheckBox(wxEmptyString, 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")); + S.AddVariableText(_("Use LPC")); + S.Id(FEUseLPCID).TieCheckBox(wxEmptyString, 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(); + /* 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(); diff --git a/src/import/ImportFFmpeg.cpp b/src/import/ImportFFmpeg.cpp index 2a96945be..42b56641d 100644 --- a/src/import/ImportFFmpeg.cpp +++ b/src/import/ImportFFmpeg.cpp @@ -37,7 +37,7 @@ Licensed under the GNU General Public License v2 or later //TODO: remove non-audio extensions #if defined(USE_FFMPEG) static const wxChar *exts[] = -{ +{ wxT("4xm"), wxT("MTV"), wxT("roq"), @@ -171,7 +171,7 @@ public: FFmpegImportPlugin(): ImportPlugin(wxArrayString(WXSIZEOF(exts),exts)) { - + } ~FFmpegImportPlugin() { } @@ -210,23 +210,23 @@ public: ///! Reads next audio frame ///\return pointer to the stream context structure to which the frame belongs to or NULL on error, or 1 if stream is not to be imported. streamContext* ReadNextFrame(); - + ///! Decodes the frame ///\param sc - stream context (from ReadNextFrame) ///\param flushing - true if flushing (no more frames left), false otherwise ///\return 0 on success, -1 if it can't decode any further int DecodeFrame(streamContext *sc, bool flushing); - + ///! Writes decoded data into WaveTracks. Called by DecodeFrame ///\param sc - stream context ///\return 0 on success, 1 on error or interruption int WriteData(streamContext *sc); - + ///! Writes extracted metadata to tags object ///\param avf - file context ///\ tags - Audacity tags object void WriteMetadata(Tags *tags); - + ///! Retrieves metadata from FFmpeg and converts to wxString ///\param avf - file context ///\ tags - Audacity tags object @@ -240,7 +240,7 @@ public: { return mNumStreams; } - + ///! Called by Import.cpp ///\return array of strings - descriptions of the streams wxArrayString *GetStreamInfo() @@ -263,7 +263,7 @@ private: int mNumStreams; //!< mNumstreams is less or equal to mFormatContext->nb_streams streamContext **mScs; //!< Array of pointers to stream contexts. Length is mNumStreams. wxArrayString *mStreamInfo; //!< Array of stream descriptions. Length is mNumStreams - + wxInt64 mProgressPos; //!< Current timestamp, file position or whatever is used as first argument for Update() wxInt64 mProgressLen; //!< Duration, total length or whatever is used as second argument for Update() @@ -317,7 +317,7 @@ ImportFileHandle *FFmpegImportPlugin::Open(wxString filename) dlg = new FFmpegNotFoundDialog(NULL); dlg->ShowModal(); delete dlg; - } + } } } if (!FFmpegLibsInst->ValidLibsLoaded()) @@ -326,7 +326,7 @@ ImportFileHandle *FFmpegImportPlugin::Open(wxString filename) return NULL; } - // Open the file for import + // Open the file for import bool success = handle->Init(); if (!success) { delete handle; @@ -429,14 +429,14 @@ bool FFmpegImportFileHandle::InitCodecs() wxString strinfo; int duration = 0; if (sc->m_stream->duration > 0) - duration = sc->m_stream->duration * sc->m_stream->time_base.num / sc->m_stream->time_base.den; + duration = sc->m_stream->duration * sc->m_stream->time_base.num / sc->m_stream->time_base.den; else - duration = mFormatContext->duration / AV_TIME_BASE; + duration = mFormatContext->duration / AV_TIME_BASE; wxString bitrate = wxT(""); if (sc->m_codecCtx->bit_rate > 0) - bitrate.Printf(wxT("%d"),sc->m_codecCtx->bit_rate); + bitrate.Printf(wxT("%d"),sc->m_codecCtx->bit_rate); else - bitrate.Printf(wxT("?")); + bitrate.Printf(wxT("?")); AVDictionaryEntry *tag = av_dict_get(sc->m_stream->metadata, "language", NULL, 0); wxString lang; @@ -580,24 +580,24 @@ int FFmpegImportFileHandle::Import(TrackFactory *trackFactory, sampleDuration = ((sampleCount)mFormatContext->duration *mScs[s]->m_stream->codec->sample_rate) / AV_TIME_BASE; // printf(" OD duration samples %qi, sr %d, secs %d\n",sampleDuration, (int)mScs[s]->m_stream->codec->sample_rate,(int)sampleDuration/mScs[s]->m_stream->codec->sample_rate); - + //for each wavetrack within the stream add coded blockfiles for (int c = 0; c < mScs[s]->m_stream->codec->channels; c++) { WaveTrack *t = mChannels[s][c]; odTask->AddWaveTrack(t); - + sampleCount maxBlockSize = t->GetMaxBlockSize(); //use the maximum blockfile size to divide the sections (about 11secs per blockfile at 44.1khz) for (sampleCount i = 0; i < sampleDuration; i += maxBlockSize) { sampleCount blockLen = maxBlockSize; if (i + blockLen > sampleDuration) blockLen = sampleDuration - i; - + t->AppendCoded(mFilename, i, blockLen, c,ODTask::eODFFMPEG); - - // This only works well for single streams since we assume + + // This only works well for single streams since we assume // each stream is of the same duration and channels - res = mProgress->Update(i+sampleDuration*c+ sampleDuration*mScs[s]->m_stream->codec->channels*s, + res = mProgress->Update(i+sampleDuration*c+ sampleDuration*mScs[s]->m_stream->codec->channels*s, sampleDuration*mScs[s]->m_stream->codec->channels*mNumStreams); if (res != eProgressSuccess) break; @@ -640,7 +640,7 @@ int FFmpegImportFileHandle::Import(TrackFactory *trackFactory, { av_free_packet(&sc->m_pkt); sc->m_pktValid = 0; - } + } } } @@ -657,7 +657,7 @@ int FFmpegImportFileHandle::Import(TrackFactory *trackFactory, { av_free_packet(&mScs[i]->m_pkt); mScs[i]->m_pktValid = 0; - } + } } } } @@ -759,22 +759,22 @@ int FFmpegImportFileHandle::WriteData(streamContext *sc) case AV_SAMPLE_FMT_U8P: ((int16_t *)tmp[chn])[index] = (int16_t) (*(uint8_t *)in - 0x80) << 8; break; - + case AV_SAMPLE_FMT_S16: case AV_SAMPLE_FMT_S16P: ((int16_t *)tmp[chn])[index] = (int16_t) *(int16_t *)in; break; - + case AV_SAMPLE_FMT_S32: case AV_SAMPLE_FMT_S32P: ((float *)tmp[chn])[index] = (float) *(int32_t *)in * (1.0 / (1 << 31)); break; - + case AV_SAMPLE_FMT_FLT: case AV_SAMPLE_FMT_FLTP: ((float *)tmp[chn])[index] = (float) *(float *)in; break; - + case AV_SAMPLE_FMT_DBL: case AV_SAMPLE_FMT_DBLP: ((float *)tmp[chn])[index] = (float) *(double *)in; @@ -800,7 +800,7 @@ int FFmpegImportFileHandle::WriteData(streamContext *sc) } free(tmp); - + // Try to update the progress indicator (and see if user wants to cancel) int updateResult = eProgressSuccess; int64_t filesize = avio_size(mFormatContext->pb);