void FormatContext::close() { if (!m_raw) return; if (isOpened()) { closeCodecContexts(); AVIOContext *avio = m_raw->pb; if (isOutput()) { OutputFormat fmt = outputFormat(); if (!(fmt.flags() & AVFMT_NOFILE) && !(m_raw->flags & AVFMT_FLAG_CUSTOM_IO)) { avio_close(m_raw->pb); } avformat_free_context(m_raw); } else { avformat_close_input(&m_raw); } m_raw = avformat_alloc_context(); m_monitor.reset(new char); m_isOpened = false; m_streamsInfoFound = false; m_headerWriten = false; // To prevent free not out custom IO, e.g. setted via raw pointer access if (m_customIO) { // Close custom IO av_freep(&avio->buffer); av_freep(&avio); m_customIO = false; } } }
void FormatContext::openOutput(const string &uri, OutputFormat format, AVDictionary **options, OptionalErrorCode ec) { clear_if(ec); if (!m_raw) { throws_if(ec, Errors::Unallocated); return; } if (isOpened()) { throws_if(ec, Errors::FormatAlreadyOpened); return; } if (format.isNull()) format = outputFormat(); else setFormat(format); if (format.isNull()) { // Guess format format = guessOutputFormat(string(), uri); if (format.isNull()) { fflog(AV_LOG_ERROR, "Can't guess output format"); throws_if(ec, Errors::FormatNullOutputFormat); return; } setFormat(format); } // Fix stream flags #if !USE_CODECPAR FF_DISABLE_DEPRECATION_WARNINGS for (size_t i = 0; i < streamsCount(); ++i) { auto st = stream(i); if (st.raw()->codec) { if (outputFormat().isFlags(AVFMT_GLOBALHEADER)) { st.raw()->codec->flags |= AV_CODEC_FLAG_GLOBAL_HEADER; } } } FF_ENABLE_DEPRECATION_WARNINGS #endif resetSocketAccess(); if (!(format.flags() & AVFMT_NOFILE)) { int sts = avio_open2(&m_raw->pb, uri.c_str(), AVIO_FLAG_WRITE, nullptr, options); if (sts < 0) { throws_if(ec, sts, ffmpeg_category()); return; } } m_uri = uri; m_isOpened = true; }