// Detect type of input file and open it if recognized. Routine // based on the av_open_input_file() libavformat function. int ufile_fopen_input(AVFormatContext **ic_ptr, const wxString &name) { wxFileName f(name); AVIOContext *pb = NULL; int err; // Open the file to prepare for probing if ((err = ufile_fopen(&pb, name, AVIO_FLAG_READ)) < 0) { goto fail; } *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, OSINPUT(name), NULL, NULL); if (err) { goto fail; } return 0; fail: if (pb) { ufile_close(pb); } *ic_ptr = NULL; return err; }
bool FLACImportFileHandle::Init() { #ifdef LEGACY_FLAC bool success = mFile->set_filename(OSINPUT(mFilename)); if (!success) { return false; } mFile->set_metadata_respond(FLAC__METADATA_TYPE_STREAMINFO); mFile->set_metadata_respond(FLAC__METADATA_TYPE_VORBIS_COMMENT); FLAC::Decoder::File::State state = mFile->init(); if (state != FLAC__FILE_DECODER_OK) { return false; } #else if (!mHandle.Open(mFilename, wxT("rb"))) { return false; } // Even though there is an init() method that takes a filename, use the one that // takes a file handle because wxWidgets can open a file with a Unicode name and // libflac can't (under Windows). // // Responsibility for closing the file is passed to libflac. // (it happens when mFile->finish() is called) bool result = mFile->init(mHandle.fp())?true:false; mHandle.Detach(); if (result != FLAC__STREAM_DECODER_INIT_STATUS_OK) { return false; } #endif mFile->process_until_end_of_metadata(); #ifdef LEGACY_FLAC state = mFile->get_state(); if (state != FLAC__FILE_DECODER_OK) { return false; } #else // not necessary to check state, error callback will catch errors, but here's how: if (mFile->get_state() > FLAC__STREAM_DECODER_READ_FRAME) { return false; } #endif if (!mFile->is_valid() || mFile->get_was_error()) { // This probably is not a FLAC file at all return false; } return true; }
// // Returns the full path of program module (.exe, .dll, .so, .dylib) containing address // wxString FileNames::PathFromAddr(void *addr) { wxFileName name; #if defined(__WXMAC__) || defined(__WXGTK__) Dl_info info; if (dladdr(addr, &info)) { char realname[PLATFORM_MAX_PATH + 1]; int len; name = LAT1CTOWX(info.dli_fname); len = readlink(OSINPUT(name.GetFullPath()), realname, PLATFORM_MAX_PATH); if (len > 0) { realname[len] = 0; name.SetFullName(LAT1CTOWX(realname)); } } #elif defined(__WXMSW__) && defined(_UNICODE) // The GetModuleHandlEx() function did not appear until Windows XP and // GetModuleFileName() did appear until Windows 2000, so we have to // check for them at runtime. typedef BOOL (WINAPI *getmodulehandleex)(DWORD dwFlags, LPCWSTR lpModuleName, HMODULE* phModule); typedef DWORD (WINAPI *getmodulefilename)(HMODULE hModule, LPWCH lpFilename, DWORD nSize); getmodulehandleex gmhe = (getmodulehandleex) GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "GetModuleHandleExW"); getmodulefilename gmfn = (getmodulefilename) GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "GetModuleFileNameW"); if (gmhe != NULL && gmfn != NULL) { HMODULE module; if (gmhe(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, (LPTSTR) addr, &module)) { TCHAR path[MAX_PATH]; DWORD nSize; nSize = gmfn(module, path, MAX_PATH); if (nSize && nSize < MAX_PATH) { name = LAT1CTOWX(path); } } } #endif return name.GetFullPath(); }
bool FLACImportFileHandle::Init() { #ifdef EXPERIMENTAL_OD_FLAC mDecoderTask=new ODDecodeFlacTask; ODFlacDecoder* odDecoder = (ODFlacDecoder*)mDecoderTask->CreateFileDecoder(mFilename); if(!odDecoder || !odDecoder->ReadHeader()) { //DELETE the task only if it failed to read - otherwise the OD man takes care of it. delete mDecoderTask; return false; } //copy the meta data over to the class mSampleRate=odDecoder->mSampleRate; mNumChannels=odDecoder->mNumChannels; mBitsPerSample=odDecoder->mBitsPerSample; mNumSamples=odDecoder->mNumSamples; mBitsPerSample=odDecoder->mBitsPerSample; mFormat=odDecoder->mFormat; mStreamInfoDone=true; return true; #endif #ifdef LEGACY_FLAC bool success = mFile->set_filename(OSINPUT(mFilename)); if (!success) { return false; } mFile->set_metadata_respond(FLAC__METADATA_TYPE_STREAMINFO); mFile->set_metadata_respond(FLAC__METADATA_TYPE_VORBIS_COMMENT); FLAC::Decoder::File::State state = mFile->init(); if (state != FLAC__FILE_DECODER_OK) { return false; } #else if (!mHandle.Open(mFilename, wxT("rb"))) { return false; } // Even though there is an init() method that takes a filename, use the one that // takes a file handle because wxWidgets can open a file with a Unicode name and // libflac can't (under Windows). // // Responsibility for closing the file is passed to libflac. // (it happens when mFile->finish() is called) bool result = mFile->init(mHandle.fp())?true:false; mHandle.Detach(); if (result != FLAC__STREAM_DECODER_INIT_STATUS_OK) { return false; } #endif mFile->process_until_end_of_metadata(); #ifdef LEGACY_FLAC state = mFile->get_state(); if (state != FLAC__FILE_DECODER_OK) { return false; } #else // not necessary to check state, error callback will catch errors, but here's how: if (mFile->get_state() > FLAC__STREAM_DECODER_READ_FRAME) { return false; } #endif if (!mFile->is_valid() || mFile->get_was_error()) { // This probably is not a FLAC file at all return false; } return true; }
bool ExportFFmpeg::Init(const char *shortname, AudacityProject *project, Tags *metadata) { int err; //FFmpegLibsInst->LoadLibs(NULL,true); //Loaded at startup or from Prefs now if (!FFmpegLibsInst->ValidLibsLoaded()) return false; FFmpegLibsInst->av_log_set_callback(av_log_wx_callback); AVFormatParameters fpOutFile; // See if libavformat has modules that can write our output format. If so, mEncFormatDesc // will describe the functions used to write the format (used internally by libavformat) // and the default video/audio codecs that the format uses. if ((mEncFormatDesc = FFmpegLibsInst->guess_format(shortname, OSINPUT(mName), NULL)) == NULL) { wxLogMessage(wxT("FFmpeg : ERROR - Can't determine format description for file \"%s\"."), mName.c_str()); return false; } // mEncFormatCtx is used by libavformat to carry around context data re our output file. if ((mEncFormatCtx = FFmpegLibsInst->av_alloc_format_context()) == NULL) { wxLogMessage(wxT("FFmpeg : ERROR - Can't allocate output format context.")); return false; } // 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 ((mEncAudioStream = FFmpegLibsInst->av_new_stream(mEncFormatCtx, 1)) == NULL) { wxLogMessage(wxT("FFmpeg : ERROR - Can't add audio stream to output file \"%s\"."), mName.c_str()); return false; } mEncAudioStream->id = 0; mEncFormatCtx->timestamp = 0; // Open the output file. if (!(mEncFormatDesc->flags & AVFMT_NOFILE)) { if ((err = ufile_fopen(&mEncFormatCtx->pb, mName, URL_WRONLY)) < 0) { wxLogMessage(wxT("FFmpeg : ERROR - Can't open output file \"%s\" to write. Error code is %d."), mName.c_str(),err); return false; } } // Set default parameters on the format context. memset(&fpOutFile, 0, sizeof(AVFormatParameters)); if ((err = FFmpegLibsInst->av_set_parameters(mEncFormatCtx, &fpOutFile)) < 0) { wxLogMessage(wxT("FFmpeg : ERROR - Can't set output parameters for output file \"%s\". Error code is %d."), mName.c_str(),err); return false; } // I have no idea what is this mEncFormatCtx->preload = (int)(0.5 * AV_TIME_BASE); mEncFormatCtx->max_delay = (int)(0.7 * AV_TIME_BASE); // Open the audio stream's codec and initialise any stream related data. if (!InitCodecs(project)) return false; if (metadata == NULL) metadata = project->GetTags(); // Add metadata BEFORE writing the header. // At the moment that works with ffmpeg-git and ffmpeg-0.5 for MP4. if (ExportFFmpegOptions::fmts[mSubFormat].canmetadata) { mSupportsUTF8 = ExportFFmpegOptions::fmts[mSubFormat].canutf8; AddTags(metadata); } // Write headers to the output file. if ((err = FFmpegLibsInst->av_write_header(mEncFormatCtx)) < 0) { wxLogMessage(wxT("FFmpeg : ERROR - Can't write headers to output file \"%s\". Error code is %d."), mName.c_str(),err); return false; } return true; }
bool ExportFFmpeg::Init(const char *shortname, AudacityProject *project, const Tags *metadata, int subformat) { int err; //FFmpegLibsInst->LoadLibs(NULL,true); //Loaded at startup or from Prefs now if (!FFmpegLibsInst->ValidLibsLoaded()) return false; av_log_set_callback(av_log_wx_callback); // See if libavformat has modules that can write our output format. If so, mEncFormatDesc // will describe the functions used to write the format (used internally by libavformat) // and the default video/audio codecs that the format uses. if ((mEncFormatDesc = av_guess_format(shortname, OSINPUT(mName), NULL)) == NULL) { wxMessageBox(wxString::Format(_("FFmpeg : ERROR - Can't determine format description for file \"%s\"."), mName.c_str()), _("FFmpeg Error"), wxOK|wxCENTER|wxICON_EXCLAMATION); return false; } // mEncFormatCtx is used by libavformat to carry around context data re our output file. if ((mEncFormatCtx = avformat_alloc_context()) == NULL) { wxMessageBox(wxString::Format(_("FFmpeg : ERROR - Can't allocate output format context.")), _("FFmpeg Error"), wxOK|wxCENTER|wxICON_EXCLAMATION); return false; } // 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 ((mEncAudioStream = avformat_new_stream(mEncFormatCtx, NULL)) == NULL) { wxMessageBox(wxString::Format(_("FFmpeg : ERROR - Can't add audio stream to output file \"%s\"."), mName.c_str()), _("FFmpeg Error"), wxOK|wxCENTER|wxICON_EXCLAMATION); return false; } mEncAudioStream->id = 0; // Open the output file. if (!(mEncFormatDesc->flags & AVFMT_NOFILE)) { if ((err = ufile_fopen(&mEncFormatCtx->pb, mName, AVIO_FLAG_WRITE)) < 0) { wxMessageBox(wxString::Format(wxT("FFmpeg : ERROR - Can't open output file \"%s\" to write. Error code is %d."), mName.c_str(), err), _("FFmpeg Error"), wxOK|wxCENTER|wxICON_EXCLAMATION); return false; } } // Open the audio stream's codec and initialise any stream related data. if (!InitCodecs(project)) return false; if (metadata == NULL) metadata = project->GetTags(); // Add metadata BEFORE writing the header. // At the moment that works with ffmpeg-git and ffmpeg-0.5 for MP4. if (GetCanMetaData(subformat)) { mSupportsUTF8 = ExportFFmpegOptions::fmts[mSubFormat].canutf8; AddTags(metadata); } // Write headers to the output file. if ((err = avformat_write_header(mEncFormatCtx, NULL)) < 0) { wxMessageBox(wxString::Format(_("FFmpeg : ERROR - Can't write headers to output file \"%s\". Error code is %d."), mName.c_str(),err), _("FFmpeg Error"), wxOK|wxCENTER|wxICON_EXCLAMATION); return false; } return true; }
bool ExportFFmpeg::Init(const char *shortname, AudacityProject *project, const Tags *metadata, int subformat) { // This will undo the acquisition of resources along any early exit path: auto deleter = [](ExportFFmpeg *This) { if (This) This->FreeResources(); }; std::unique_ptr<ExportFFmpeg, decltype(deleter)> cleanup{ this, deleter }; int err; //FFmpegLibsInst->LoadLibs(NULL,true); //Loaded at startup or from Prefs now if (!FFmpegLibsInst->ValidLibsLoaded()) return false; av_log_set_callback(av_log_wx_callback); // See if libavformat has modules that can write our output format. If so, mEncFormatDesc // will describe the functions used to write the format (used internally by libavformat) // and the default video/audio codecs that the format uses. if ((mEncFormatDesc = av_guess_format(shortname, OSINPUT(mName), NULL)) == NULL) { wxMessageBox(wxString::Format(_("FFmpeg : ERROR - Can't determine format description for file \"%s\"."), mName.c_str()), _("FFmpeg Error"), wxOK|wxCENTER|wxICON_EXCLAMATION); return false; } // mEncFormatCtx is used by libavformat to carry around context data re our output file. mEncFormatCtx.reset(avformat_alloc_context()); if (!mEncFormatCtx) { wxMessageBox(wxString::Format(_("FFmpeg : ERROR - Can't allocate output format context.")), _("FFmpeg Error"), wxOK|wxCENTER|wxICON_EXCLAMATION); return false; } // 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 ((mEncAudioStream = avformat_new_stream(mEncFormatCtx.get(), NULL)) == NULL) { wxMessageBox(wxString::Format(_("FFmpeg : ERROR - Can't add audio stream to output file \"%s\"."), mName.c_str()), _("FFmpeg Error"), wxOK|wxCENTER|wxICON_EXCLAMATION); return false; } // Documentation for avformat_new_stream says // "User is required to call avcodec_close() and avformat_free_context() to clean // up the allocation by avformat_new_stream()." // We use smart pointers that ensure these cleanups either in their destructors or // sooner if they are reset. These are std::unique_ptr with nondefault deleter // template parameters. // mEncFormatCtx takes care of avformat_free_context(), so // mEncAudioStream can be a plain pointer. // mEncAudioCodecCtx now becomes responsible for closing the codec: mEncAudioCodecCtx.reset(mEncAudioStream->codec); mEncAudioStream->id = 0; // Open the output file. if (!(mEncFormatDesc->flags & AVFMT_NOFILE)) { if ((err = ufile_fopen(&mEncFormatCtx->pb, mName, AVIO_FLAG_WRITE)) < 0) { wxMessageBox(wxString::Format(wxT("FFmpeg : ERROR - Can't open output file \"%s\" to write. Error code is %d."), mName.c_str(), err), _("FFmpeg Error"), wxOK|wxCENTER|wxICON_EXCLAMATION); return false; } // Give mUfileCloser responsibility mUfileCloser.reset(mEncFormatCtx->pb); } // Open the audio stream's codec and initialise any stream related data. if (!InitCodecs(project)) return false; if (metadata == NULL) metadata = project->GetTags(); // Add metadata BEFORE writing the header. // At the moment that works with ffmpeg-git and ffmpeg-0.5 for MP4. if (GetCanMetaData(subformat)) { mSupportsUTF8 = ExportFFmpegOptions::fmts[mSubFormat].canutf8; AddTags(metadata); } // Write headers to the output file. if ((err = avformat_write_header(mEncFormatCtx.get(), NULL)) < 0) { wxMessageBox(wxString::Format(_("FFmpeg : ERROR - Can't write headers to output file \"%s\". Error code is %d."), mName.c_str(),err), _("FFmpeg Error"), wxOK|wxCENTER|wxICON_EXCLAMATION); return false; } // Only now, we can keep all the resources until Finalize(). // Cancel the local cleanup. cleanup.release(); return true; }