int MediaDecoder::setupFromAudioData(const AudioFormat format) { int ret; if (decoderCtx_) avcodec_close(decoderCtx_); // Increase analyze time to solve synchronization issues between callers. static const unsigned MAX_ANALYZE_DURATION = 30; // time in seconds inputCtx_->max_analyze_duration = MAX_ANALYZE_DURATION * AV_TIME_BASE; RING_DBG("Finding stream info"); #if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(53, 8, 0) ret = av_find_stream_info(inputCtx_); #else ret = avformat_find_stream_info(inputCtx_, NULL); #endif RING_DBG("Finding stream info DONE"); if (ret < 0) { // workaround for this bug: // http://patches.libav.org/patch/22541/ if (ret == -1) ret = AVERROR_INVALIDDATA; char errBuf[64] = {0}; // print nothing for unknown errors if (av_strerror(ret, errBuf, sizeof errBuf) < 0) errBuf[0] = '\0'; // always fail here RING_ERR("Could not find stream info: %s", errBuf); return -1; } // find the first audio stream from the input for (size_t i = 0; streamIndex_ == -1 && i < inputCtx_->nb_streams; ++i) if (inputCtx_->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO) streamIndex_ = i; if (streamIndex_ == -1) { RING_ERR("Could not find audio stream"); return -1; } // Get a pointer to the codec context for the video stream avStream_ = inputCtx_->streams[streamIndex_]; decoderCtx_ = avStream_->codec; if (decoderCtx_ == 0) { RING_ERR("Decoder context is NULL"); return -1; } // find the decoder for the audio stream inputDecoder_ = avcodec_find_decoder(decoderCtx_->codec_id); if (!inputDecoder_) { RING_ERR("Unsupported codec"); return -1; } decoderCtx_->thread_count = std::thread::hardware_concurrency(); decoderCtx_->channels = format.nb_channels; decoderCtx_->sample_rate = format.sample_rate; RING_DBG("Audio decoding using %s with %s", inputDecoder_->name, format.toString().c_str()); if (emulateRate_) { RING_DBG("Using framerate emulation"); startTime_ = av_gettime(); } #if LIBAVCODEC_VERSION_MAJOR >= 55 decoderCtx_->refcounted_frames = 1; #endif ret = avcodec_open2(decoderCtx_, inputDecoder_, NULL); if (ret) { RING_ERR("Could not open codec"); return -1; } return 0; }